diff --git a/Gopkg.lock b/Gopkg.lock index 2a1e0c3..4320b14 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -50,6 +50,12 @@ revision = "b026a6fd291f00736db60738f4e83a79d26359cb" version = "v2.2.0" +[[projects]] + branch = "master" + name = "github.com/robotn/gohook" + packages = ["."] + revision = "3dccbf0083168096c576bf62abb3d5d4c916e2ea" + [[projects]] name = "github.com/shirou/gopsutil" packages = [ @@ -88,11 +94,11 @@ "unix", "windows" ] - revision = "49385e6e15226593f68b26af201feec29d5bba22" + revision = "d0be0721c37eeb5299f245a996a483160fc36940" [solve-meta] analyzer-name = "dep" analyzer-version = 1 - inputs-digest = "0fd06dbf29cbad04968ef5a7c12e61c18ab8595bcb2d30c9f35698f0873916d1" + inputs-digest = "b1299bcf48c5b674a219acd0d53d6e1dc9cd44f60a9448f74d2fb623eaf9b00a" solver-name = "gps-cdcl" solver-version = 1 diff --git a/cdeps/README.md b/cdeps/README.md index b6354dd..3303cf7 100644 --- a/cdeps/README.md +++ b/cdeps/README.md @@ -1 +1 @@ -C language dependent package, better to compilation. You need to follow the relevant agreement and LICENSE. \ No newline at end of file +C language dependent package, better to compilation. \ No newline at end of file diff --git a/vendor/github.com/robotn/gohook/.gitignore b/vendor/github.com/robotn/gohook/.gitignore new file mode 100644 index 0000000..daf913b --- /dev/null +++ b/vendor/github.com/robotn/gohook/.gitignore @@ -0,0 +1,24 @@ +# Compiled Object files, Static and Dynamic libs (Shared Objects) +*.o +*.a +*.so + +# Folders +_obj +_test + +# Architecture specific extensions/prefixes +*.[568vq] +[568vq].out + +*.cgo1.go +*.cgo2.c +_cgo_defun.c +_cgo_gotypes.go +_cgo_export.* + +_testmain.go + +*.exe +*.test +*.prof diff --git a/vendor/github.com/robotn/gohook/LICENSE b/vendor/github.com/robotn/gohook/LICENSE new file mode 100644 index 0000000..9cecc1d --- /dev/null +++ b/vendor/github.com/robotn/gohook/LICENSE @@ -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. + + {one line to give the program's name and a brief idea of what it does.} + Copyright (C) {year} {name of author} + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +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: + + {project} Copyright (C) {year} {fullname} + 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/vendor/github.com/robotn/gohook/README.md b/vendor/github.com/robotn/gohook/README.md new file mode 100644 index 0000000..be006df --- /dev/null +++ b/vendor/github.com/robotn/gohook/README.md @@ -0,0 +1,21 @@ +# gohook + +This is a work in progress. + +```Go +package main + +import ( + "fmt" + + "go-vgo/robotn/gohook" +) + +func main() { + // hook.AsyncHook() + veve := hook.AddEvent("v") + if veve == 0 { + fmt.Println("v...") + } +} +``` \ No newline at end of file diff --git a/vendor/github.com/robotn/gohook/event/goEvent.h b/vendor/github.com/robotn/gohook/event/goEvent.h new file mode 100644 index 0000000..b3467fb --- /dev/null +++ b/vendor/github.com/robotn/gohook/event/goEvent.h @@ -0,0 +1,252 @@ +// Copyright 2016 The go-vgo Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// https://github.com/go-vgo/robotgo/blob/master/LICENSE +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#ifdef HAVE_CONFIG_H + #include +#endif + +#include "pub.h" + + +void dispatch_proc(iohook_event * const event) { + char buffer[256] = { 0 }; + size_t length = snprintf(buffer, sizeof(buffer), + "id=%i,when=%" PRIu64 ",mask=0x%X", + event->type, event->time, event->mask); + + switch (event->type) { + case EVENT_KEY_PRESSED: + // If the escape key is pressed, naturally terminate the program. + if (event->data.keyboard.keycode == VC_ESCAPE) { + // int status = hook_stop(); + // switch (status) { + // // System level errors. + // case IOHOOK_ERROR_OUT_OF_MEMORY: + // loggerProc(LOG_LEVEL_ERROR, "Failed to allocate memory. (%#X)", status); + // break; + + // case IOHOOK_ERROR_X_RECORD_GET_CONTEXT: + // // NOTE This is the only platform specific error that occurs on hook_stop(). + // loggerProc(LOG_LEVEL_ERROR, "Failed to get XRecord context. (%#X)", status); + // break; + + // // Default error. + // case IOHOOK_FAILURE: + // default: + // loggerProc(LOG_LEVEL_ERROR, "An unknown hook error occurred. (%#X)", status); + // break; + // } + } + case EVENT_KEY_RELEASED: + snprintf(buffer + length, sizeof(buffer) - length, + ",keycode=%u,rawcode=0x%X", + event->data.keyboard.keycode, event->data.keyboard.rawcode); + int akeyCode = (uint16_t) event->data.keyboard.keycode; + + if (event->data.keyboard.keycode == VC_ESCAPE + && atoi(cevent) == 11) { + int stopEvent = stop_event(); + // printf("stop_event%d\n", stopEvent); + cstatus = 0; + } + + // printf("atoi(str)---%d\n", atoi(cevent)); + if (akeyCode == atoi(cevent)) { + int stopEvent = stop_event(); + // printf("%d\n", stopEvent); + cstatus = 0; + } + break; + + case EVENT_KEY_TYPED: + snprintf(buffer + length, sizeof(buffer) - length, + ",keychar=%lc,rawcode=%u", + (uint16_t) event->data.keyboard.keychar, + event->data.keyboard.rawcode); + + #ifdef WE_REALLY_WANT_A_POINTER + char *buf = malloc (6); + #else + char buf[6]; + #endif + + sprintf(buf, "%lc", (uint16_t) event->data.keyboard.keychar); + + #ifdef WE_REALLY_WANT_A_POINTER + free (buf); + #endif + + if (strcmp(buf, cevent) == 0) { + int stopEvent = stop_event(); + // printf("%d\n", stopEvent); + cstatus = 0; + } + // return (char*) event->data.keyboard.keychar; + break; + + case EVENT_MOUSE_PRESSED: + case EVENT_MOUSE_RELEASED: + case EVENT_MOUSE_CLICKED: + case EVENT_MOUSE_MOVED: + case EVENT_MOUSE_DRAGGED: + snprintf(buffer + length, sizeof(buffer) - length, + ",x=%i,y=%i,button=%i,clicks=%i", + event->data.mouse.x, event->data.mouse.y, + event->data.mouse.button, event->data.mouse.clicks); + + int abutton = event->data.mouse.button; + int aclicks = event->data.mouse.clicks; + int amouse = -1; + + if (strcmp(cevent, "mleft") == 0) { + amouse = 1; + } + if (strcmp(cevent, "mright") == 0) { + amouse = 2; + } + if (strcmp(cevent, "wheelDown") == 0) { + amouse = 4; + } + if (strcmp(cevent, "wheelUp") == 0) { + amouse = 5; + } + if (strcmp(cevent, "wheelLeft") == 0) { + amouse = 6; + } + if (strcmp(cevent, "wheelRight") == 0) { + amouse = 7; + } + if (abutton == amouse && aclicks == 1) { + int stopEvent = stop_event(); + cstatus = 0; + } + + break; + + case EVENT_MOUSE_WHEEL: + snprintf(buffer + length, sizeof(buffer) - length, + ",type=%i,amount=%i,rotation=%i", + event->data.wheel.type, event->data.wheel.amount, + event->data.wheel.rotation); + break; + + default: + break; + } + + // fprintf(stdout, "----%s\n", buffer); +} + +int add_event(char *key_event) { + // (uint16_t *) + cevent = key_event; + // Set the logger callback for library output. + hookSetlogger(&loggerProc); + + // Set the event callback for IOhook events. + hook_set_dispatch_proc(&dispatch_proc); + // Start the hook and block. + // NOTE If EVENT_HOOK_ENABLED was delivered, the status will always succeed. + int status = hook_run(); + + switch (status) { + case IOHOOK_SUCCESS: + // Everything is ok. + break; + + // System level errors. + case IOHOOK_ERROR_OUT_OF_MEMORY: + loggerProc(LOG_LEVEL_ERROR, "Failed to allocate memory. (%#X)", status); + break; + + + // X11 specific errors. + case IOHOOK_ERROR_X_OPEN_DISPLAY: + loggerProc(LOG_LEVEL_ERROR, "Failed to open X11 display. (%#X)", status); + break; + + case IOHOOK_ERROR_X_RECORD_NOT_FOUND: + loggerProc(LOG_LEVEL_ERROR, "Unable to locate XRecord extension. (%#X)", status); + break; + + case IOHOOK_ERROR_X_RECORD_ALLOC_RANGE: + loggerProc(LOG_LEVEL_ERROR, "Unable to allocate XRecord range. (%#X)", status); + break; + + case IOHOOK_ERROR_X_RECORD_CREATE_CONTEXT: + loggerProc(LOG_LEVEL_ERROR, "Unable to allocate XRecord context. (%#X)", status); + break; + + case IOHOOK_ERROR_X_RECORD_ENABLE_CONTEXT: + loggerProc(LOG_LEVEL_ERROR, "Failed to enable XRecord context. (%#X)", status); + break; + + + // Windows specific errors. + case IOHOOK_ERROR_SET_WINDOWS_HOOK_EX: + loggerProc(LOG_LEVEL_ERROR, "Failed to register low level windows hook. (%#X)", status); + break; + + + // Darwin specific errors. + case IOHOOK_ERROR_AXAPI_DISABLED: + loggerProc(LOG_LEVEL_ERROR, "Failed to enable access for assistive devices. (%#X)", status); + break; + + case IOHOOK_ERROR_CREATE_EVENT_PORT: + loggerProc(LOG_LEVEL_ERROR, "Failed to create apple event port. (%#X)", status); + break; + + case IOHOOK_ERROR_CREATE_RUN_LOOP_SOURCE: + loggerProc(LOG_LEVEL_ERROR, "Failed to create apple run loop source. (%#X)", status); + break; + + case IOHOOK_ERROR_GET_RUNLOOP: + loggerProc(LOG_LEVEL_ERROR, "Failed to acquire apple run loop. (%#X)", status); + break; + + case IOHOOK_ERROR_CREATE_OBSERVER: + loggerProc(LOG_LEVEL_ERROR, "Failed to create apple run loop observer. (%#X)", status); + break; + + // Default error. + case IOHOOK_FAILURE: + default: + loggerProc(LOG_LEVEL_ERROR, "An unknown hook error occurred. (%#X)", status); + break; + } + + // return status; + // printf("%d\n", status); + return cstatus; +} + +int stop_event(){ + int status = hook_stop(); + switch (status) { + // System level errors. + case IOHOOK_ERROR_OUT_OF_MEMORY: + loggerProc(LOG_LEVEL_ERROR, "Failed to allocate memory. (%#X)", status); + break; + + case IOHOOK_ERROR_X_RECORD_GET_CONTEXT: + // NOTE This is the only platform specific error that occurs on hook_stop(). + loggerProc(LOG_LEVEL_ERROR, "Failed to get XRecord context. (%#X)", status); + break; + + // Default error. + case IOHOOK_FAILURE: + default: + // loggerProc(LOG_LEVEL_ERROR, "An unknown hook error occurred. (%#X)", status); + break; + } + + return status; +} \ No newline at end of file diff --git a/vendor/github.com/robotn/gohook/event/os.h b/vendor/github.com/robotn/gohook/event/os.h new file mode 100644 index 0000000..ab46989 --- /dev/null +++ b/vendor/github.com/robotn/gohook/event/os.h @@ -0,0 +1,49 @@ +#pragma once +#ifndef OS_H +#define OS_H + +/* Python versions under 2.5 don't support this macro, but it's not + * terribly difficult to replicate: */ +#ifndef PyModule_AddIntMacro + #define PyModule_AddIntMacro(module, macro) \ + PyModule_AddIntConstant(module, #macro, macro) +#endif /* PyModule_AddIntMacro */ + +#if !defined(IS_MACOSX) && defined(__APPLE__) && defined(__MACH__) + #define IS_MACOSX +#endif /* IS_MACOSX */ + +#if !defined(IS_WINDOWS) && (defined(WIN32) || defined(_WIN32) || \ + defined(__WIN32__) || defined(__WINDOWS__) || defined(__CYGWIN__)) + #define IS_WINDOWS +#endif /* IS_WINDOWS */ + +#if !defined(USE_X11) && !defined(NUSE_X11) && !defined(IS_MACOSX) && !defined(IS_WINDOWS) + #define USE_X11 +#endif /* USE_X11 */ + +#if defined(IS_WINDOWS) + #define STRICT /* Require use of exact types. */ + #define WIN32_LEAN_AND_MEAN 1 /* Speed up compilation. */ + #include +#elif !defined(IS_MACOSX) && !defined(USE_X11) + #error "Sorry, this platform isn't supported yet!" +#endif + +/* Interval to align by for large buffers (e.g. bitmaps). */ +/* Must be a power of 2. */ +#ifndef BYTE_ALIGN + #define BYTE_ALIGN 4 /* Bytes to align pixel buffers to. */ + /* #include */ + /* #define BYTE_ALIGN (sizeof(size_t)) */ +#endif /* BYTE_ALIGN */ + +#if BYTE_ALIGN == 0 + /* No alignment needed. */ + #define ADD_PADDING(width) (width) +#else + /* Aligns given width to padding. */ + #define ADD_PADDING(width) (BYTE_ALIGN + (((width) - 1) & ~(BYTE_ALIGN - 1))) +#endif + +#endif /* OS_H */ diff --git a/vendor/github.com/robotn/gohook/event/pub.h b/vendor/github.com/robotn/gohook/event/pub.h new file mode 100644 index 0000000..408f113 --- /dev/null +++ b/vendor/github.com/robotn/gohook/event/pub.h @@ -0,0 +1,95 @@ +// Copyright 2016 The go-vgo Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// https://github.com/go-vgo/robotgo/blob/master/LICENSE +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#include "os.h" + +#if defined(IS_MACOSX) + #include "../hook/darwin/input_c.h" + #include "../hook/darwin/hook_c.h" + #include "../hook/darwin/event_c.h" + #include "../hook/darwin/properties_c.h" +#elif defined(USE_X11) + //#define USE_XKBCOMMON 0 + #include "../hook/x11/input_c.h" + #include "../hook/x11/hook_c.h" + #include "../hook/x11/event_c.h" + #include "../hook/x11/properties_c.h" +#elif defined(IS_WINDOWS) + #include "../hook/windows/input_c.h" + #include "../hook/windows/hook_c.h" + #include "../hook/windows/event_c.h" + #include "../hook/windows/properties_c.h" +#endif + +#include +#include +#include +#include +#include +#include "../hook/iohook.h" + + +int vccode[100]; +int codesz; + +char *cevent; +int rrevent; +// uint16_t *cevent; +int cstatus = 1; + + +int stop_event(); +int add_event(char *key_event); +// int allEvent(char *key_event); +int allEvent(char *key_event, int vcode[], int size); + +// NOTE: The following callback executes on the same thread that hook_run() is called +// from. + +struct _MEvent { + uint8_t id; + size_t mask; + uint16_t keychar; + // char *keychar; + size_t x; + uint8_t y; + uint8_t bytesPerPixel; +}; + +typedef struct _MEvent MEvent; +// typedef MMBitmap *MMBitmapRef; + +MEvent mEvent; + + +bool loggerProc(unsigned int level, const char *format, ...) { + bool status = false; + + va_list args; + switch (level) { + #ifdef USE_DEBUG + case LOG_LEVEL_DEBUG: + case LOG_LEVEL_INFO: + va_start(args, format); + status = vfprintf(stdout, format, args) >= 0; + va_end(args); + break; + #endif + + case LOG_LEVEL_WARN: + case LOG_LEVEL_ERROR: + va_start(args, format); + status = vfprintf(stderr, format, args) >= 0; + va_end(args); + break; + } + + return status; +} \ No newline at end of file diff --git a/vendor/github.com/robotn/gohook/hook.go b/vendor/github.com/robotn/gohook/hook.go new file mode 100644 index 0000000..a5b3b91 --- /dev/null +++ b/vendor/github.com/robotn/gohook/hook.go @@ -0,0 +1,35 @@ +package hook + +/* +#cgo darwin CFLAGS: -x objective-c -Wno-deprecated-declarations +#cgo darwin LDFLAGS: -framework Cocoa +#cgo linux CFLAGS:-I/usr/src +#cgo linux LDFLAGS: -L/usr/src -lX11 -lXtst +#cgo linux LDFLAGS: -lX11-xcb -lxcb -lxcb-xkb -lxkbcommon -lxkbcommon-x11 +#cgo windows LDFLAGS: -lgdi32 -luser32 + +#include "event/goEvent.h" +// #include "event/hook_async.h" +*/ +import "C" + +import( + // "fmt" + "unsafe" +) + +// AddEvent add event listener +func AddEvent(key string) int { + cs := C.CString(key) + + eve := C.add_event(cs) + geve := int(eve) + + defer C.free(unsafe.Pointer(cs)) + return geve +} + +// StopEvent stop event listener +func StopEvent() { + C.stop_event() +} \ No newline at end of file diff --git a/vendor/github.com/robotn/gohook/hook/darwin/event_c.h b/vendor/github.com/robotn/gohook/hook/darwin/event_c.h new file mode 100644 index 0000000..c621b71 --- /dev/null +++ b/vendor/github.com/robotn/gohook/hook/darwin/event_c.h @@ -0,0 +1,235 @@ + +#ifdef HAVE_CONFIG_H + #include +#endif + +#include +#include +#include +#include +#include "../iohook.h" + +// #include "../logger_c.h" +#include "input.h" + +// TODO Possibly relocate to input helper. +static inline CGEventFlags get_key_event_mask(iohook_event * const event) { + CGEventFlags native_mask = 0x00; + + if (event->mask & (MASK_SHIFT)) { native_mask |= kCGEventFlagMaskShift; } + if (event->mask & (MASK_CTRL)) { native_mask |= kCGEventFlagMaskControl; } + if (event->mask & (MASK_META)) { native_mask |= kCGEventFlagMaskControl; } + if (event->mask & (MASK_ALT)) { native_mask |= kCGEventFlagMaskAlternate; } + + if (event->type == EVENT_KEY_PRESSED || event->type == EVENT_KEY_RELEASED || event->type == EVENT_KEY_TYPED) { + switch (event->data.keyboard.keycode) { + case VC_KP_0: + case VC_KP_1: + case VC_KP_2: + case VC_KP_3: + case VC_KP_4: + case VC_KP_5: + case VC_KP_6: + case VC_KP_7: + case VC_KP_8: + case VC_KP_9: + + case VC_NUM_LOCK: + case VC_KP_ENTER: + case VC_KP_MULTIPLY: + case VC_KP_ADD: + case VC_KP_SEPARATOR: + case VC_KP_SUBTRACT: + case VC_KP_DIVIDE: + case VC_KP_COMMA: + native_mask |= kCGEventFlagMaskNumericPad; + break; + } + } + + return native_mask; +} + +static inline void post_key_event(iohook_event * const event) { + bool is_pressed = event->type == EVENT_KEY_PRESSED; + + CGEventSourceRef src = CGEventSourceCreate(kCGEventSourceStateHIDSystemState); + CGEventRef cg_event = CGEventCreateKeyboardEvent(src, + (CGKeyCode) scancode_to_keycode(event->data.keyboard.keycode), + is_pressed); + + CGEventSetFlags(cg_event, get_key_event_mask(event)); + CGEventPost(kCGHIDEventTap, cg_event); // kCGSessionEventTap also works. + CFRelease(cg_event); + CFRelease(src); +} + +static inline void post_mouse_button_event(iohook_event * const event, bool is_pressed) { + CGMouseButton mouse_button; + CGEventType mouse_type; + if (event->data.mouse.button == MOUSE_BUTTON1) { + if (is_pressed) { + mouse_type = kCGEventLeftMouseDown; + } + else { + mouse_type = kCGEventLeftMouseUp; + } + mouse_button = kCGMouseButtonLeft; + } + else if (event->data.mouse.button == MOUSE_BUTTON2) { + if (is_pressed) { + mouse_type = kCGEventRightMouseDown; + } + else { + mouse_type = kCGEventRightMouseUp; + } + mouse_button = kCGMouseButtonRight; + } + else { + if (is_pressed) { + mouse_type = kCGEventOtherMouseDown; + } + else { + mouse_type = kCGEventOtherMouseUp; + } + mouse_button = event->data.mouse.button - 1; + } + + CGEventSourceRef src = CGEventSourceCreate(kCGEventSourceStateHIDSystemState); + CGEventRef cg_event = CGEventCreateMouseEvent(src, + mouse_type, + CGPointMake( + (CGFloat) event->data.mouse.x, + (CGFloat) event->data.mouse.y + ), + mouse_button + ); + CGEventPost(kCGHIDEventTap, cg_event); // kCGSessionEventTap also works. + CFRelease(cg_event); + CFRelease(src); +} + +static inline void post_mouse_wheel_event(iohook_event * const event) { + // FIXME Should I create a source event with the coords? + // It seems to automagically use the current location of the cursor. + // Two options: Query the mouse, move it to x/y, scroll, then move back + // OR disable x/y for scroll events on Windows & X11. + CGScrollEventUnit scroll_unit; + if (event->data.wheel.type == WHEEL_BLOCK_SCROLL) { + // Scrolling data is line-based. + scroll_unit = kCGScrollEventUnitLine; + } + else { + // Scrolling data is pixel-based. + scroll_unit = kCGScrollEventUnitPixel; + } + + CGEventSourceRef src = CGEventSourceCreate(kCGEventSourceStateHIDSystemState); + CGEventRef cg_event = CGEventCreateScrollWheelEvent(src, + kCGScrollEventUnitLine, + // TODO Currently only support 1 wheel axis. + (CGWheelCount) 1, // 1 for Y-only, 2 for Y-X, 3 for Y-X-Z + event->data.wheel.amount * event->data.wheel.rotation); + + CGEventPost(kCGHIDEventTap, cg_event); // kCGSessionEventTap also works. + CFRelease(cg_event); + CFRelease(src); +} + +static inline void post_mouse_motion_event(iohook_event * const event) { + CGEventSourceRef src = CGEventSourceCreate(kCGEventSourceStateHIDSystemState); + CGEventRef cg_event; + if (event->mask >> 8 == 0x00) { + // No mouse flags. + cg_event = CGEventCreateMouseEvent(src, + kCGEventMouseMoved, + CGPointMake( + (CGFloat) event->data.mouse.x, + (CGFloat) event->data.mouse.y + ), + 0 + ); + } + else if (event->mask & MASK_BUTTON1) { + cg_event = CGEventCreateMouseEvent(src, + kCGEventLeftMouseDragged, + CGPointMake( + (CGFloat) event->data.mouse.x, + (CGFloat) event->data.mouse.y + ), + kCGMouseButtonLeft + ); + } + else if (event->mask & MASK_BUTTON2) { + cg_event = CGEventCreateMouseEvent(src, + kCGEventRightMouseDragged, + CGPointMake( + (CGFloat) event->data.mouse.x, + (CGFloat) event->data.mouse.y + ), + kCGMouseButtonRight + ); + } + else { + cg_event = CGEventCreateMouseEvent(src, + kCGEventOtherMouseDragged, + CGPointMake( + (CGFloat) event->data.mouse.x, + (CGFloat) event->data.mouse.y + ), + (event->mask >> 8) - 1 + ); + } + + // kCGSessionEventTap also works. + CGEventPost(kCGHIDEventTap, cg_event); + CFRelease(cg_event); + CFRelease(src); +} + +IOHOOK_API void hook_post_event(iohook_event * const event) { + switch (event->type) { + case EVENT_KEY_PRESSED: + case EVENT_KEY_RELEASED: + post_key_event(event); + break; + + + case EVENT_MOUSE_PRESSED: + post_mouse_button_event(event, true); + break; + + case EVENT_MOUSE_RELEASED: + post_mouse_button_event(event, false); + break; + + case EVENT_MOUSE_CLICKED: + post_mouse_button_event(event, true); + post_mouse_button_event(event, false); + break; + + case EVENT_MOUSE_WHEEL: + post_mouse_wheel_event(event); + break; + + + case EVENT_MOUSE_MOVED: + case EVENT_MOUSE_DRAGGED: + post_mouse_motion_event(event); + break; + + + case EVENT_KEY_TYPED: + // FIXME Ignoreing EVENT_KEY_TYPED events. + + case EVENT_HOOK_ENABLED: + case EVENT_HOOK_DISABLED: + // Ignore hook enabled / disabled events. + + default: + // Ignore any other garbage. + logger(LOG_LEVEL_WARN, "%s [%u]: Ignoring post event type %#X\n", + __FUNCTION__, __LINE__, event->type); + break; + } +} diff --git a/vendor/github.com/robotn/gohook/hook/darwin/hook_c.h b/vendor/github.com/robotn/gohook/hook/darwin/hook_c.h new file mode 100644 index 0000000..cb8b609 --- /dev/null +++ b/vendor/github.com/robotn/gohook/hook/darwin/hook_c.h @@ -0,0 +1,1362 @@ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#ifndef USE_WEAK_IMPORT + #include +#endif +#include +#ifdef USE_OBJC + #include + #include +#endif + +#include +#include +#include +#include "../iohook.h" +// #include "../logger_c.h" +#include "input.h" + +typedef struct _hook_info { + CFMachPortRef port; + CFRunLoopSourceRef source; + CFRunLoopObserverRef observer; +} hook_info; + +#ifdef USE_OBJC +static id auto_release_pool; +#endif + +// Event runloop reference. +CFRunLoopRef event_loop; + +// Flag to restart the event tap incase of timeout. +static Boolean restart_tap = false; + +// Modifiers for tracking key masks. +static uint16_t current_modifiers = 0x0000; + +// Required to transport messages between the main runloop and our thread for +// Unicode lookups. +#define KEY_BUFFER_SIZE 4 +typedef struct { + CGEventRef event; + UniChar buffer[KEY_BUFFER_SIZE]; + UniCharCount length; +} TISMessage; +TISMessage *tis_message; + +#ifdef USE_WEAK_IMPORT +// Required to dynamically check for AXIsProcessTrustedWithOptions availability. +extern void dispatch_get_main_queue() __attribute__((weak_import)); +extern void dispatch_sync_f(dispatch_queue_t queue, void *context, void (*function)(void *)) __attribute__((weak_import)); +#else +#if __MAC_OS_X_VERSION_MAX_ALLOWED <= 1050 +typedef void* dispatch_queue_t; +#endif +static dispatch_queue_t (*dispatch_get_main_queue_f)(); +static void (*dispatch_sync_f_f)(dispatch_queue_t, void *, void (*function)(void *)); +#endif + +#if ! defined(USE_CARBON_LEGACY) && defined(USE_COREFOUNDATION) +static CFRunLoopSourceRef src_msg_port; +static CFRunLoopObserverRef observer; + +static pthread_cond_t msg_port_cond = PTHREAD_COND_INITIALIZER; +static pthread_mutex_t msg_port_mutex = PTHREAD_MUTEX_INITIALIZER; +#endif + +// Click count globals. +static unsigned short click_count = 0; +static CGEventTimestamp click_time = 0; +static unsigned short int click_button = MOUSE_NOBUTTON; +static bool mouse_dragged = false; + +// Structure for the current Unix epoch in milliseconds. +static struct timeval system_time; + +// Virtual event pointer. +static iohook_event event; + +// Event dispatch callback. +static dispatcher_t dispatcher = NULL; + +IOHOOK_API void hook_set_dispatch_proc(dispatcher_t dispatch_proc) { + logger(LOG_LEVEL_DEBUG, "%s [%u]: Setting new dispatch callback to %#p.\n", + __FUNCTION__, __LINE__, dispatch_proc); + + dispatcher = dispatch_proc; +} + +// Send out an event if a dispatcher was set. +static inline void dispatch_event(iohook_event *const event) { + if (dispatcher != NULL) { + logger(LOG_LEVEL_DEBUG, "%s [%u]: Dispatching event type %u.\n", + __FUNCTION__, __LINE__, event->type); + + dispatcher(event); + } + else { + logger(LOG_LEVEL_WARN, "%s [%u]: No dispatch callback set!\n", + __FUNCTION__, __LINE__); + } +} + + +// Set the native modifier mask for future events. +static inline void set_modifier_mask(uint16_t mask) { + current_modifiers |= mask; +} + +// Unset the native modifier mask for future events. +static inline void unset_modifier_mask(uint16_t mask) { + current_modifiers ^= mask; +} + +// Get the current native modifier mask state. +static inline uint16_t get_modifiers() { + return current_modifiers; +} + +// Initialize the modifier mask to the current modifiers. +static void initialize_modifiers() { + current_modifiers = 0x0000; + + if (CGEventSourceKeyState(kCGEventSourceStateCombinedSessionState, kVK_Shift)) { + set_modifier_mask(MASK_SHIFT_L); + } + if (CGEventSourceKeyState(kCGEventSourceStateCombinedSessionState, kVK_RightShift)) { + set_modifier_mask(MASK_SHIFT_R); + } + if (CGEventSourceKeyState(kCGEventSourceStateCombinedSessionState, kVK_Control)) { + set_modifier_mask(MASK_CTRL_L); + } + if (CGEventSourceKeyState(kCGEventSourceStateCombinedSessionState, kVK_RightControl)) { + set_modifier_mask(MASK_CTRL_R); + } + if (CGEventSourceKeyState(kCGEventSourceStateCombinedSessionState, kVK_Option)) { + set_modifier_mask(MASK_ALT_L); + } + if (CGEventSourceKeyState(kCGEventSourceStateCombinedSessionState, kVK_RightOption)) { + set_modifier_mask(MASK_ALT_R); + } + if (CGEventSourceKeyState(kCGEventSourceStateCombinedSessionState, kVK_Command)) { + set_modifier_mask(MASK_META_L); + } + if (CGEventSourceKeyState(kCGEventSourceStateCombinedSessionState, kVK_RightCommand)) { + set_modifier_mask(MASK_META_R); + } + + if (CGEventSourceButtonState(kCGEventSourceStateCombinedSessionState, kVK_LBUTTON)) { + set_modifier_mask(MASK_BUTTON1); + } + if (CGEventSourceButtonState(kCGEventSourceStateCombinedSessionState, kVK_RBUTTON)) { + set_modifier_mask(MASK_BUTTON2); + } + if (CGEventSourceButtonState(kCGEventSourceStateCombinedSessionState, kVK_MBUTTON)) { + set_modifier_mask(MASK_BUTTON3); + } + if (CGEventSourceButtonState(kCGEventSourceStateCombinedSessionState, kVK_XBUTTON1)) { + set_modifier_mask(MASK_BUTTON4); + } + if (CGEventSourceButtonState(kCGEventSourceStateCombinedSessionState, kVK_XBUTTON2)) { + set_modifier_mask(MASK_BUTTON5); + } + + if (CGEventSourceFlagsState(kCGEventSourceStateCombinedSessionState) & kCGEventFlagMaskAlphaShift) { + set_modifier_mask(MASK_CAPS_LOCK); + } + // Best I can tell, OS X does not support Num or Scroll lock. + unset_modifier_mask(MASK_NUM_LOCK); + unset_modifier_mask(MASK_SCROLL_LOCK); +} + + +// Wrap keycode_to_unicode with some null checks. +static void keycode_to_lookup(void *info) { + TISMessage *data = (TISMessage *) info; + + if (data != NULL && data->event != NULL) { + // Preform Unicode lookup. + data->length = keycode_to_unicode(data->event, data->buffer, KEY_BUFFER_SIZE); + } +} + +#if ! defined(USE_CARBON_LEGACY) && defined(USE_COREFOUNDATION) +void message_port_status_proc(CFRunLoopObserverRef observer, CFRunLoopActivity activity, void *info) { + switch (activity) { + case kCFRunLoopExit: + // Acquire a lock on the msg_port and signal that anyone waiting + // should continue. + pthread_mutex_lock(&msg_port_mutex); + pthread_cond_broadcast(&msg_port_cond); + pthread_mutex_unlock(&msg_port_mutex); + break; + + default: + logger(LOG_LEVEL_WARN, "%s [%u]: Unhandled RunLoop activity! (%#X)\n", + __FUNCTION__, __LINE__, (unsigned int) activity); + break; + } +} + +// Runloop to execute KeyCodeToString on the "Main" runloop due to an +// undocumented thread safety requirement. +static void message_port_proc(void *info) { + // Lock the msg_port mutex as we enter the main runloop. + pthread_mutex_lock(&msg_port_mutex); + + keycode_to_lookup(info); + + // Unlock the msg_port mutex to signal to the hook_thread that we have + // finished on the main runloop. + pthread_cond_broadcast(&msg_port_cond); + pthread_mutex_unlock(&msg_port_mutex); +} + +static int start_message_port_runloop() { + int status = IOHOOK_FAILURE; + + if (tis_message != NULL) { + // Create a runloop observer for the main runloop. + observer = CFRunLoopObserverCreate( + kCFAllocatorDefault, + kCFRunLoopExit, //kCFRunLoopEntry | kCFRunLoopExit, //kCFRunLoopAllActivities, + true, + 0, + message_port_status_proc, + NULL + ); + + if (observer != NULL) { + pthread_mutex_lock(&msg_port_mutex); + + CFRunLoopSourceContext context = { + .version = 0, + .info = tis_message, + .retain = NULL, + .release = NULL, + .copyDescription = NULL, + .equal = NULL, + .hash = NULL, + .schedule = NULL, + .cancel = NULL, + .perform = message_port_proc + }; + + CFRunLoopRef main_loop = CFRunLoopGetMain(); + + src_msg_port = CFRunLoopSourceCreate(kCFAllocatorDefault, 0, &context); + if (src_msg_port != NULL) { + CFRunLoopAddSource(main_loop, src_msg_port, kCFRunLoopDefaultMode); + CFRunLoopAddObserver(main_loop, observer, kCFRunLoopDefaultMode); + + logger(LOG_LEVEL_DEBUG, "%s [%u]: Successful.\n", + __FUNCTION__, __LINE__); + + status = IOHOOK_SUCCESS; + } + else { + logger(LOG_LEVEL_ERROR, "%s [%u]: CFRunLoopSourceCreate failure!\n", + __FUNCTION__, __LINE__); + + status = IOHOOK_ERROR_CREATE_RUN_LOOP_SOURCE; + } + + pthread_mutex_unlock(&msg_port_mutex); + } + else { + logger(LOG_LEVEL_ERROR, "%s [%u]: CFRunLoopObserverCreate failure!\n", + __FUNCTION__, __LINE__); + + status = IOHOOK_ERROR_CREATE_OBSERVER; + } + } + else { + logger(LOG_LEVEL_ERROR, "%s [%u]: No available TIS Message pointer.\n", + __FUNCTION__, __LINE__); + } + + return status; +} + +static void stop_message_port_runloop() { + CFRunLoopRef main_loop = CFRunLoopGetMain(); + + if (CFRunLoopContainsObserver(main_loop, observer, kCFRunLoopDefaultMode)) { + CFRunLoopRemoveObserver(main_loop, observer, kCFRunLoopDefaultMode); + CFRunLoopObserverInvalidate(observer); + } + + if (CFRunLoopContainsSource(main_loop, src_msg_port, kCFRunLoopDefaultMode)) { + CFRunLoopRemoveSource(main_loop, src_msg_port, kCFRunLoopDefaultMode); + CFRelease(src_msg_port); + } + + observer = NULL; + src_msg_port = NULL; + + logger(LOG_LEVEL_DEBUG, "%s [%u]: Successful.\n", + __FUNCTION__, __LINE__); +} +#endif + +static void hook_status_proc(CFRunLoopObserverRef observer, CFRunLoopActivity activity, void *info) { + uint64_t timestamp = mach_absolute_time(); + + switch (activity) { + case kCFRunLoopEntry: + // Populate the hook start event. + event.time = timestamp; + event.reserved = 0x00; + + event.type = EVENT_HOOK_ENABLED; + event.mask = 0x00; + + // Fire the hook start event. + dispatch_event(&event); + break; + + case kCFRunLoopExit: + // Populate the hook stop event. + event.time = timestamp; + event.reserved = 0x00; + + event.type = EVENT_HOOK_DISABLED; + event.mask = 0x00; + + // Fire the hook stop event. + dispatch_event(&event); + break; + + default: + logger(LOG_LEVEL_WARN, "%s [%u]: Unhandled RunLoop activity! (%#X)\n", + __FUNCTION__, __LINE__, (unsigned int) activity); + break; + } +} + +static inline void process_key_pressed(uint64_t timestamp, CGEventRef event_ref) { + UInt64 keycode = CGEventGetIntegerValueField(event_ref, kCGKeyboardEventKeycode); + + // Populate key pressed event. + event.time = timestamp; + event.reserved = 0x00; + + event.type = EVENT_KEY_PRESSED; + event.mask = get_modifiers(); + + event.data.keyboard.keycode = keycode_to_scancode(keycode); + event.data.keyboard.rawcode = keycode; + event.data.keyboard.keychar = CHAR_UNDEFINED; + + logger(LOG_LEVEL_INFO, "%s [%u]: Key %#X pressed. (%#X)\n", + __FUNCTION__, __LINE__, event.data.keyboard.keycode, event.data.keyboard.rawcode); + + // Fire key pressed event. + dispatch_event(&event); + + // If the pressed event was not consumed... + if (event.reserved ^ 0x01) { + tis_message->event = event_ref; + tis_message->length = 0; + bool is_runloop_main = CFEqual(event_loop, CFRunLoopGetMain()); + + #ifdef USE_WEAK_IMPORT + if (dispatch_sync_f != NULL && dispatch_get_main_queue != NULL && !is_runloop_main) { + logger(LOG_LEVEL_DEBUG, "%s [%u]: Using dispatch_sync_f for key typed events.\n", __FUNCTION__, __LINE__); + dispatch_sync_f(dispatch_get_main_queue(), tis_message, &keycode_to_lookup); + } + #else + if (dispatch_sync_f_f != NULL && dispatch_get_main_queue_f != NULL && !is_runloop_main) { + logger(LOG_LEVEL_DEBUG, "%s [%u]: Using *dispatch_sync_f_f for key typed events.\n", __FUNCTION__, __LINE__); + (*dispatch_sync_f_f)((*dispatch_get_main_queue_f)(), tis_message, &keycode_to_lookup); + } + #endif + #if ! defined(USE_CARBON_LEGACY) && defined(USE_COREFOUNDATION) + else if (!is_runloop_main) { + // Lock for code dealing with the main runloop. + pthread_mutex_lock(&msg_port_mutex); + + // Check to see if the main runloop is still running. + // TOOD I would rather this be a check on hook_enable(), + // but it makes the usage complicated by requiring a separate + // thread for the main runloop and hook registration. + CFStringRef mode = CFRunLoopCopyCurrentMode(CFRunLoopGetMain()); + if (mode != NULL) { + CFRelease(mode); + + // Lookup the Unicode representation for this event. + //CFRunLoopSourceContext context = { .version = 0 }; + //CFRunLoopSourceGetContext(src_msg_port, &context); + + // Get the run loop context info pointer. + //TISMessage *info = (TISMessage *) context.info; + + // Set the event pointer. + //info->event = event_ref; + + // Signal the custom source and wakeup the main runloop. + CFRunLoopSourceSignal(src_msg_port); + CFRunLoopWakeUp(CFRunLoopGetMain()); + + // Wait for a lock while the main runloop processes they key typed event. + pthread_cond_wait(&msg_port_cond, &msg_port_mutex); + } + else { + logger(LOG_LEVEL_WARN, "%s [%u]: Failed to signal RunLoop main!\n", + __FUNCTION__, __LINE__); + } + + // Unlock for code dealing with the main runloop. + pthread_mutex_unlock(&msg_port_mutex); + } + #endif + else { + keycode_to_lookup(tis_message); + } + unsigned int i; + for (i= 0; i < tis_message->length; i++) { + // Populate key typed event. + event.time = timestamp; + event.reserved = 0x00; + + event.type = EVENT_KEY_TYPED; + event.mask = get_modifiers(); + + event.data.keyboard.keycode = VC_UNDEFINED; + event.data.keyboard.rawcode = keycode; + event.data.keyboard.keychar = tis_message->buffer[i]; + + logger(LOG_LEVEL_INFO, "%s [%u]: Key %#X typed. (%lc)\n", + __FUNCTION__, __LINE__, event.data.keyboard.keycode, + (wint_t) event.data.keyboard.keychar); + + // Populate key typed event. + dispatch_event(&event); + } + } +} + +static inline void process_key_released(uint64_t timestamp, CGEventRef event_ref) { + UInt64 keycode = CGEventGetIntegerValueField(event_ref, kCGKeyboardEventKeycode); + + // Populate key released event. + event.time = timestamp; + event.reserved = 0x00; + + event.type = EVENT_KEY_RELEASED; + event.mask = get_modifiers(); + + event.data.keyboard.keycode = keycode_to_scancode(keycode); + event.data.keyboard.rawcode = keycode; + event.data.keyboard.keychar = CHAR_UNDEFINED; + + logger(LOG_LEVEL_INFO, "%s [%u]: Key %#X released. (%#X)\n", + __FUNCTION__, __LINE__, event.data.keyboard.keycode, event.data.keyboard.rawcode); + + // Fire key released event. + dispatch_event(&event); +} + +static inline void process_modifier_changed(uint64_t timestamp, CGEventRef event_ref) { + CGEventFlags event_mask = CGEventGetFlags(event_ref); + UInt64 keycode = CGEventGetIntegerValueField(event_ref, kCGKeyboardEventKeycode); + + logger(LOG_LEVEL_INFO, "%s [%u]: Modifiers Changed for key %#X. (%#X)\n", + __FUNCTION__, __LINE__, (unsigned long) keycode, (unsigned int) event_mask); + + /* Because Apple treats modifier keys differently than normal key + * events, any changes to the modifier keys will require a key state + * change to be fired manually. + * + * NOTE Left and right keyboard masks like NX_NEXTLSHIFTKEYMASK exist and + * appear to be in use on Darwin, however they are removed by comment or + * preprocessor with a note that reads "device-dependent (really?)." To + * ensure compatability, we will do this the verbose way. + * + * NOTE The masks for scroll and number lock are set in the key event. + */ + if (keycode == kVK_Shift) { + if (event_mask & kCGEventFlagMaskShift) { + // Process as a key pressed event. + set_modifier_mask(MASK_SHIFT_L); + process_key_pressed(timestamp, event_ref); + } + else { + // Process as a key released event. + unset_modifier_mask(MASK_SHIFT_L); + process_key_released(timestamp, event_ref); + } + } + else if (keycode == kVK_Control) { + if (event_mask & kCGEventFlagMaskControl) { + // Process as a key pressed event. + set_modifier_mask(MASK_CTRL_L); + process_key_pressed(timestamp, event_ref); + } + else { + // Process as a key released event. + unset_modifier_mask(MASK_CTRL_L); + process_key_released(timestamp, event_ref); + } + } + else if (keycode == kVK_Command) { + if (event_mask & kCGEventFlagMaskCommand) { + // Process as a key pressed event. + set_modifier_mask(MASK_META_L); + process_key_pressed(timestamp, event_ref); + } + else { + // Process as a key released event. + unset_modifier_mask(MASK_META_L); + process_key_released(timestamp, event_ref); + } + } + else if (keycode == kVK_Option) { + if (event_mask & kCGEventFlagMaskAlternate) { + // Process as a key pressed event. + set_modifier_mask(MASK_ALT_L); + process_key_pressed(timestamp, event_ref); + } + else { + // Process as a key released event. + unset_modifier_mask(MASK_ALT_L); + process_key_released(timestamp, event_ref); + } + } + else if (keycode == kVK_RightShift) { + if (event_mask & kCGEventFlagMaskShift) { + // Process as a key pressed event. + set_modifier_mask(MASK_SHIFT_R); + process_key_pressed(timestamp, event_ref); + } + else { + // Process as a key released event. + unset_modifier_mask(MASK_SHIFT_R); + process_key_released(timestamp, event_ref); + } + } + else if (keycode == kVK_RightControl) { + if (event_mask & kCGEventFlagMaskControl) { + // Process as a key pressed event. + set_modifier_mask(MASK_CTRL_R); + process_key_pressed(timestamp, event_ref); + } + else { + // Process as a key released event. + unset_modifier_mask(MASK_CTRL_R); + process_key_released(timestamp, event_ref); + } + } + else if (keycode == kVK_RightCommand) { + if (event_mask & kCGEventFlagMaskCommand) { + // Process as a key pressed event. + set_modifier_mask(MASK_META_R); + process_key_pressed(timestamp, event_ref); + } + else { + // Process as a key released event. + unset_modifier_mask(MASK_META_R); + process_key_released(timestamp, event_ref); + } + } + else if (keycode == kVK_RightOption) { + if (event_mask & kCGEventFlagMaskAlternate) { + // Process as a key pressed event. + set_modifier_mask(MASK_ALT_R); + process_key_pressed(timestamp, event_ref); + } + else { + // Process as a key released event. + unset_modifier_mask(MASK_ALT_R); + process_key_released(timestamp, event_ref); + } + } + /* FIXME This should produce a modifier mask for the caps lock key! + else if (keycode == kVK_CapsLock) { + // Process as a key pressed event. + process_key_pressed(timestamp, event_ref); + + // Set the caps-lock flag for release. + caps_down = true; + } + */ +} + +/* These events are totally undocumented for the CGEvent type, but are required to grab media and caps-lock keys. + */ +static inline void process_system_key(uint64_t timestamp, CGEventRef event_ref) { + if( CGEventGetType(event_ref) == NX_SYSDEFINED) { + #ifdef USE_OBJC + // Contributed by Iván Munsuri Ibáñez + id event_data = objc_msgSend((id) objc_getClass("NSEvent"), sel_registerName("eventWithCGEvent:"), event_ref); + int subtype = (int) objc_msgSend(event_data, sel_registerName("subtype")); + #else + CFDataRef data = CGEventCreateData(kCFAllocatorDefault, event_ref); + //CFIndex len = CFDataGetLength(data); + UInt8 *buffer = malloc(12); + // CFDataRef cf_data = CFDataCreate(NULL, [nsData bytes], [nsData length]); + CFDataGetBytes(data, CFRangeMake(108, 12), buffer); + UInt32 subtype = CFSwapInt32BigToHost(*((UInt32 *) buffer)); + #endif + if (subtype == 8) { + #ifdef USE_OBJC + // int data = (int) objc_msgSend(event_data, sel_registerName("data1")); + uint16_t data = (uint16_t) objc_msgSend(event_data, sel_registerName("data1")) + #endif + + // int + uint16_t key_code = ((uint16_t)data & 0xFFFF0000) >> 16; + uint16_t key_flags = ((uint16_t)data & 0xFFFF); + //int key_state = (key_flags & 0xFF00) >> 8; + bool key_down = (key_flags & 0x1) > 0; + + if (key_code == NX_KEYTYPE_CAPS_LOCK) { + // It doesn't appear like we can modify the event coming in, so we will fabricate a new event. + CGEventSourceRef src = CGEventSourceCreate(kCGEventSourceStateHIDSystemState); + CGEventRef ns_event = CGEventCreateKeyboardEvent(src, kVK_CapsLock, key_down); + CGEventSetFlags(ns_event, CGEventGetFlags(event_ref)); + + if (key_down) { + process_key_pressed(timestamp, ns_event); + } + else { + process_key_released(timestamp, ns_event); + } + + CFRelease(ns_event); + CFRelease(src); + } + else if (key_code == NX_KEYTYPE_SOUND_UP) { + // It doesn't appear like we can modify the event coming in, so we will fabricate a new event. + CGEventSourceRef src = CGEventSourceCreate(kCGEventSourceStateHIDSystemState); + CGEventRef ns_event = CGEventCreateKeyboardEvent(src, kVK_VolumeUp, key_down); + CGEventSetFlags(ns_event, CGEventGetFlags(event_ref)); + + if (key_down) { + process_key_pressed(timestamp, ns_event); + } + else { + process_key_released(timestamp, ns_event); + } + + CFRelease(ns_event); + CFRelease(src); + } + else if (key_code == NX_KEYTYPE_SOUND_DOWN) { + // It doesn't appear like we can modify the event coming in, so we will fabricate a new event. + CGEventSourceRef src = CGEventSourceCreate(kCGEventSourceStateHIDSystemState); + CGEventRef ns_event = CGEventCreateKeyboardEvent(src, kVK_VolumeDown, key_down); + CGEventSetFlags(ns_event, CGEventGetFlags(event_ref)); + + if (key_down) { + process_key_pressed(timestamp, ns_event); + } + else { + process_key_released(timestamp, ns_event); + } + + CFRelease(ns_event); + CFRelease(src); + } + else if (key_code == NX_KEYTYPE_MUTE) { + // It doesn't appear like we can modify the event coming in, so we will fabricate a new event. + CGEventSourceRef src = CGEventSourceCreate(kCGEventSourceStateHIDSystemState); + CGEventRef ns_event = CGEventCreateKeyboardEvent(src, kVK_Mute, key_down); + CGEventSetFlags(ns_event, CGEventGetFlags(event_ref)); + + if (key_down) { + process_key_pressed(timestamp, ns_event); + } + else { + process_key_released(timestamp, ns_event); + } + + CFRelease(ns_event); + CFRelease(src); + } + + else if (key_code == NX_KEYTYPE_EJECT) { + // It doesn't appear like we can modify the event coming in, so we will fabricate a new event. + CGEventSourceRef src = CGEventSourceCreate(kCGEventSourceStateHIDSystemState); + CGEventRef ns_event = CGEventCreateKeyboardEvent(src, kVK_NX_Eject, key_down); + CGEventSetFlags(ns_event, CGEventGetFlags(event_ref)); + + if (key_down) { + process_key_pressed(timestamp, ns_event); + } + else { + process_key_released(timestamp, ns_event); + } + + CFRelease(ns_event); + CFRelease(src); + } + else if (key_code == NX_KEYTYPE_PLAY) { + // It doesn't appear like we can modify the event coming in, so we will fabricate a new event. + CGEventSourceRef src = CGEventSourceCreate(kCGEventSourceStateHIDSystemState); + CGEventRef ns_event = CGEventCreateKeyboardEvent(src, kVK_MEDIA_Play, key_down); + CGEventSetFlags(ns_event, CGEventGetFlags(event_ref)); + + if (key_down) { + process_key_pressed(timestamp, ns_event); + } + else { + process_key_released(timestamp, ns_event); + } + + CFRelease(ns_event); + CFRelease(src); + } + else if (key_code == NX_KEYTYPE_FAST) { + // It doesn't appear like we can modify the event coming in, so we will fabricate a new event. + CGEventSourceRef src = CGEventSourceCreate(kCGEventSourceStateHIDSystemState); + CGEventRef ns_event = CGEventCreateKeyboardEvent(src, kVK_MEDIA_Next, key_down); + CGEventSetFlags(ns_event, CGEventGetFlags(event_ref)); + + if (key_down) { + process_key_pressed(timestamp, ns_event); + } + else { + process_key_released(timestamp, ns_event); + } + + CFRelease(ns_event); + CFRelease(src); + } + else if (key_code == NX_KEYTYPE_REWIND) { + // It doesn't appear like we can modify the event coming in, so we will fabricate a new event. + CGEventSourceRef src = CGEventSourceCreate(kCGEventSourceStateHIDSystemState); + CGEventRef ns_event = CGEventCreateKeyboardEvent(src, kVK_MEDIA_Previous, key_down); + CGEventSetFlags(ns_event, CGEventGetFlags(event_ref)); + + if (key_down) { + process_key_pressed(timestamp, ns_event); + } + else { + process_key_released(timestamp, ns_event); + } + + CFRelease(ns_event); + CFRelease(src); + } + } + + #ifndef USE_OBJC + free(buffer); + CFRelease(data); + #endif + } +} + + +static inline void process_button_pressed(uint64_t timestamp, CGEventRef event_ref, uint16_t button) { + // Track the number of clicks. + if (button == click_button && (long int) (timestamp - click_time) <= hook_get_multi_click_time()) { + if (click_count < USHRT_MAX) { + click_count++; + } + else { + logger(LOG_LEVEL_WARN, "%s [%u]: Click count overflow detected!\n", + __FUNCTION__, __LINE__); + } + } + else { + // Reset the click count. + click_count = 1; + + // Set the previous button. + click_button = button; + } + + // Save this events time to calculate the click_count. + click_time = timestamp; + + CGPoint event_point = CGEventGetLocation(event_ref); + + // Populate mouse pressed event. + event.time = timestamp; + event.reserved = 0x00; + + event.type = EVENT_MOUSE_PRESSED; + event.mask = get_modifiers(); + + event.data.mouse.button = button; + event.data.mouse.clicks = click_count; + event.data.mouse.x = event_point.x; + event.data.mouse.y = event_point.y; + + logger(LOG_LEVEL_INFO, "%s [%u]: Button %u pressed %u time(s). (%u, %u)\n", + __FUNCTION__, __LINE__, event.data.mouse.button, event.data.mouse.clicks, + event.data.mouse.x, event.data.mouse.y); + + // Fire mouse pressed event. + dispatch_event(&event); +} + +static inline void process_button_released(uint64_t timestamp, CGEventRef event_ref, uint16_t button) { + CGPoint event_point = CGEventGetLocation(event_ref); + + // Populate mouse released event. + event.time = timestamp; + event.reserved = 0x00; + + event.type = EVENT_MOUSE_RELEASED; + event.mask = get_modifiers(); + + event.data.mouse.button = button; + event.data.mouse.clicks = click_count; + event.data.mouse.x = event_point.x; + event.data.mouse.y = event_point.y; + + logger(LOG_LEVEL_INFO, "%s [%u]: Button %u released %u time(s). (%u, %u)\n", + __FUNCTION__, __LINE__, event.data.mouse.button, event.data.mouse.clicks, + event.data.mouse.x, event.data.mouse.y); + + // Fire mouse released event. + dispatch_event(&event); + + // If the pressed event was not consumed... + if (event.reserved ^ 0x01 && mouse_dragged != true) { + // Populate mouse clicked event. + event.time = timestamp; + event.reserved = 0x00; + + event.type = EVENT_MOUSE_CLICKED; + event.mask = get_modifiers(); + + event.data.mouse.button = button; + event.data.mouse.clicks = click_count; + event.data.mouse.x = event_point.x; + event.data.mouse.y = event_point.y; + + logger(LOG_LEVEL_INFO, "%s [%u]: Button %u clicked %u time(s). (%u, %u)\n", + __FUNCTION__, __LINE__, event.data.mouse.button, event.data.mouse.clicks, + event.data.mouse.x, event.data.mouse.y); + + // Fire mouse clicked event. + dispatch_event(&event); + } + + // Reset the number of clicks. + if (button == click_button && (long int) (event.time - click_time) > hook_get_multi_click_time()) { + // Reset the click count. + click_count = 0; + } +} + +static inline void process_mouse_moved(uint64_t timestamp, CGEventRef event_ref) { + // Reset the click count. + if (click_count != 0 && (long int) (timestamp - click_time) > hook_get_multi_click_time()) { + click_count = 0; + } + + CGPoint event_point = CGEventGetLocation(event_ref); + + // Populate mouse motion event. + event.time = timestamp; + event.reserved = 0x00; + + if (mouse_dragged) { + event.type = EVENT_MOUSE_DRAGGED; + } + else { + event.type = EVENT_MOUSE_MOVED; + } + event.mask = get_modifiers(); + + event.data.mouse.button = MOUSE_NOBUTTON; + event.data.mouse.clicks = click_count; + event.data.mouse.x = event_point.x; + event.data.mouse.y = event_point.y; + + logger(LOG_LEVEL_INFO, "%s [%u]: Mouse %s to %u, %u.\n", + __FUNCTION__, __LINE__, mouse_dragged ? "dragged" : "moved", + event.data.mouse.x, event.data.mouse.y); + + // Fire mouse motion event. + dispatch_event(&event); +} + +static inline void process_mouse_wheel(uint64_t timestamp, CGEventRef event_ref) { + // Reset the click count and previous button. + click_count = 1; + click_button = MOUSE_NOBUTTON; + + // Check to see what axis was rotated, we only care about axis 1 for vertical rotation. + // TODO Implement horizontal scrolling by examining axis 2. + // NOTE kCGScrollWheelEventDeltaAxis3 is currently unused. + if (CGEventGetIntegerValueField(event_ref, kCGScrollWheelEventDeltaAxis1) != 0 + || CGEventGetIntegerValueField(event_ref, kCGScrollWheelEventDeltaAxis2) != 0) { + CGPoint event_point = CGEventGetLocation(event_ref); + + // Populate mouse wheel event. + event.time = timestamp; + event.reserved = 0x00; + + event.type = EVENT_MOUSE_WHEEL; + event.mask = get_modifiers(); + + event.data.wheel.clicks = click_count; + event.data.wheel.x = event_point.x; + event.data.wheel.y = event_point.y; + + // TODO Figure out if kCGScrollWheelEventDeltaAxis2 causes mouse events with zero rotation. + if (CGEventGetIntegerValueField(event_ref, kCGScrollWheelEventIsContinuous) == 0) { + // Scrolling data is line-based. + event.data.wheel.type = WHEEL_BLOCK_SCROLL; + } + else { + // Scrolling data is pixel-based. + event.data.wheel.type = WHEEL_UNIT_SCROLL; + } + + // TODO The result of kCGScrollWheelEventIsContinuous may effect this value. + // Calculate the amount based on the Point Delta / Event Delta. Integer sign should always be homogeneous resulting in a positive result. + // NOTE kCGScrollWheelEventFixedPtDeltaAxis1 a floating point value (+0.1/-0.1) that takes acceleration into account. + // NOTE kCGScrollWheelEventPointDeltaAxis1 will not build on OS X < 10.5 + + if(CGEventGetIntegerValueField(event_ref, kCGScrollWheelEventDeltaAxis1) != 0) { + event.data.wheel.amount = CGEventGetIntegerValueField(event_ref, kCGScrollWheelEventPointDeltaAxis1) / CGEventGetIntegerValueField(event_ref, kCGScrollWheelEventDeltaAxis1); + + // Scrolling data uses a fixed-point 16.16 signed integer format (Ex: 1.0 = 0x00010000). + event.data.wheel.rotation = CGEventGetIntegerValueField(event_ref, kCGScrollWheelEventDeltaAxis1) * -1; + + } + else if(CGEventGetIntegerValueField(event_ref, kCGScrollWheelEventDeltaAxis2) != 0) { + event.data.wheel.amount = CGEventGetIntegerValueField(event_ref, kCGScrollWheelEventPointDeltaAxis2) / CGEventGetIntegerValueField(event_ref, kCGScrollWheelEventDeltaAxis2); + + // Scrolling data uses a fixed-point 16.16 signed integer format (Ex: 1.0 = 0x00010000). + event.data.wheel.rotation = CGEventGetIntegerValueField(event_ref, kCGScrollWheelEventDeltaAxis2) * -1; + } + else { + //Fail Silently if a 3rd axis gets added without changing this section of code. + event.data.wheel.amount = 0; + event.data.wheel.rotation = 0; + } + + + + if (CGEventGetIntegerValueField(event_ref, kCGScrollWheelEventDeltaAxis1) != 0) { + // Wheel Rotated Up or Down. + event.data.wheel.direction = WHEEL_VERTICAL_DIRECTION; + } + else { // data->event.u.u.detail == WheelLeft || data->event.u.u.detail == WheelRight + // Wheel Rotated Left or Right. + event.data.wheel.direction = WHEEL_HORIZONTAL_DIRECTION; + } + + logger(LOG_LEVEL_INFO, "%s [%u]: Mouse wheel type %u, rotated %i units in the %u direction at %u, %u.\n", + __FUNCTION__, __LINE__, event.data.wheel.type, + event.data.wheel.amount * event.data.wheel.rotation, + event.data.wheel.direction, + event.data.wheel.x, event.data.wheel.y); + + // Fire mouse wheel event. + dispatch_event(&event); + } +} + +CGEventRef hook_event_proc(CGEventTapProxy tap_proxy, CGEventType type, CGEventRef event_ref, void *refcon) { + // Get the local system time in UTC. + gettimeofday(&system_time, NULL); + + // Grab the native event timestap for use later.. + uint64_t timestamp = (uint64_t) CGEventGetTimestamp(event_ref); + + // Get the event class. + switch (type) { + case kCGEventKeyDown: + process_key_pressed(timestamp, event_ref); + break; + + case kCGEventKeyUp: + process_key_released(timestamp, event_ref); + break; + + case kCGEventFlagsChanged: + process_modifier_changed(timestamp, event_ref); + break; + + //b + // case NX_SYSDEFINED: + // process_system_key(timestamp, event_ref); + // break; + + case kCGEventLeftMouseDown: + set_modifier_mask(MASK_BUTTON1); + process_button_pressed(timestamp, event_ref, MOUSE_BUTTON1); + break; + + case kCGEventRightMouseDown: + set_modifier_mask(MASK_BUTTON2); + process_button_pressed(timestamp, event_ref, MOUSE_BUTTON2); + break; + + case kCGEventOtherMouseDown: + // Extra mouse buttons. + if (CGEventGetIntegerValueField(event_ref, kCGMouseEventButtonNumber) < UINT16_MAX) { + uint16_t button = (uint16_t) CGEventGetIntegerValueField(event_ref, kCGMouseEventButtonNumber) + 1; + + // Add support for mouse 4 & 5. + if (button == 4) { + set_modifier_mask(MOUSE_BUTTON4); + } + else if (button == 5) { + set_modifier_mask(MOUSE_BUTTON5); + } + + process_button_pressed(timestamp, event_ref, button); + } + break; + + case kCGEventLeftMouseUp: + unset_modifier_mask(MASK_BUTTON1); + process_button_released(timestamp, event_ref, MOUSE_BUTTON1); + break; + + case kCGEventRightMouseUp: + unset_modifier_mask(MASK_BUTTON2); + process_button_released(timestamp, event_ref, MOUSE_BUTTON2); + break; + + case kCGEventOtherMouseUp: + // Extra mouse buttons. + if (CGEventGetIntegerValueField(event_ref, kCGMouseEventButtonNumber) < UINT16_MAX) { + uint16_t button = (uint16_t) CGEventGetIntegerValueField(event_ref, kCGMouseEventButtonNumber) + 1; + + // Add support for mouse 4 & 5. + if (button == 4) { + unset_modifier_mask(MOUSE_BUTTON4); + } + else if (button == 5) { + unset_modifier_mask(MOUSE_BUTTON5); + } + + process_button_pressed(timestamp, event_ref, button); + } + break; + + + case kCGEventLeftMouseDragged: + case kCGEventRightMouseDragged: + case kCGEventOtherMouseDragged: + // FIXME The drag flag is confusing. Use prev x,y to determine click. + // Set the mouse dragged flag. + mouse_dragged = true; + process_mouse_moved(timestamp, event_ref); + break; + + case kCGEventMouseMoved: + // Set the mouse dragged flag. + mouse_dragged = false; + process_mouse_moved(timestamp, event_ref); + break; + + + case kCGEventScrollWheel: + process_mouse_wheel(timestamp, event_ref); + break; + + + #ifdef USE_DEBUG + case kCGEventNull: + logger(LOG_LEVEL_DEBUG, "%s [%u]: Ignoring kCGEventNull.\n", + __FUNCTION__, __LINE__); + break; + #endif + + default: + // Check for an old OS X bug where the tap seems to timeout for no reason. + // See: http://stackoverflow.com/questions/2969110/cgeventtapcreate-breaks-down-mysteriously-with-key-down-events#2971217 + if (type == (CGEventType) kCGEventTapDisabledByTimeout) { + logger(LOG_LEVEL_WARN, "%s [%u]: CGEventTap timeout!\n", + __FUNCTION__, __LINE__); + + // We need to restart the tap! + restart_tap = true; + CFRunLoopStop(CFRunLoopGetCurrent()); + } + else { + // In theory this *should* never execute. + logger(LOG_LEVEL_DEBUG, "%s [%u]: Unhandled Darwin event: %#X.\n", + __FUNCTION__, __LINE__, (unsigned int) type); + } + break; + } + + CGEventRef result_ref = NULL; + if (event.reserved ^ 0x01) { + result_ref = event_ref; + } + else { + logger(LOG_LEVEL_DEBUG, "%s [%u]: Consuming the current event. (%#X) (%#p)\n", + __FUNCTION__, __LINE__, type, event_ref); + } + + return result_ref; +} + +IOHOOK_API int hook_run() { + int status = IOHOOK_SUCCESS; + + do { + // Reset the restart flag... + restart_tap = false; + + // Check for accessibility each time we start the loop. + if (is_accessibility_enabled()) { + logger(LOG_LEVEL_DEBUG, "%s [%u]: Accessibility API is enabled.\n", + __FUNCTION__, __LINE__); + + // Initialize starting modifiers. + initialize_modifiers(); + + // Try and allocate memory for hook_info. + hook_info *hook = malloc(sizeof(hook_info)); + if (hook != NULL) { + // Setup the event mask to listen for. + #ifdef USE_DEBUG + CGEventMask event_mask = kCGEventMaskForAllEvents; + #else + CGEventMask event_mask = CGEventMaskBit(kCGEventKeyDown) | + CGEventMaskBit(kCGEventKeyUp) | + CGEventMaskBit(kCGEventFlagsChanged) | + + CGEventMaskBit(kCGEventLeftMouseDown) | + CGEventMaskBit(kCGEventLeftMouseUp) | + CGEventMaskBit(kCGEventLeftMouseDragged) | + + CGEventMaskBit(kCGEventRightMouseDown) | + CGEventMaskBit(kCGEventRightMouseUp) | + CGEventMaskBit(kCGEventRightMouseDragged) | + + CGEventMaskBit(kCGEventOtherMouseDown) | + CGEventMaskBit(kCGEventOtherMouseUp) | + CGEventMaskBit(kCGEventOtherMouseDragged) | + + CGEventMaskBit(kCGEventMouseMoved) | + CGEventMaskBit(kCGEventScrollWheel) | + + // NOTE This event is undocumented and used + // for caps-lock release and multi-media keys. + CGEventMaskBit(NX_SYSDEFINED); + #endif + + // Create the event tap. + hook->port = CGEventTapCreate( + kCGSessionEventTap, // kCGHIDEventTap + kCGHeadInsertEventTap, // kCGTailAppendEventTap + kCGEventTapOptionDefault, // kCGEventTapOptionListenOnly See Bug #22 + event_mask, + hook_event_proc, + NULL); + + if (hook->port != NULL) { + logger(LOG_LEVEL_DEBUG, "%s [%u]: CGEventTapCreate Successful.\n", + __FUNCTION__, __LINE__); + + // Create the runloop event source from the event tap. + hook->source = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, hook->port, 0); + if (hook->source != NULL) { + logger(LOG_LEVEL_DEBUG, "%s [%u]: CFMachPortCreateRunLoopSource successful.\n", + __FUNCTION__, __LINE__); + + event_loop = CFRunLoopGetCurrent(); + if (event_loop != NULL) { + logger(LOG_LEVEL_DEBUG, "%s [%u]: CFRunLoopGetCurrent successful.\n", + __FUNCTION__, __LINE__); + + // Create run loop observers. + hook->observer = CFRunLoopObserverCreate( + kCFAllocatorDefault, + kCFRunLoopEntry | kCFRunLoopExit, //kCFRunLoopAllActivities, + true, + 0, + hook_status_proc, + NULL); + + if (hook->observer != NULL) { + logger(LOG_LEVEL_DEBUG, "%s [%u]: CFRunLoopObserverCreate successful.\n", + __FUNCTION__, __LINE__); + + tis_message = (TISMessage *) calloc(1, sizeof(TISMessage)); + if (tis_message != NULL) { + if (! CFEqual(event_loop, CFRunLoopGetMain())) { + #ifdef USE_WEAK_IMPORT + if (dispatch_sync_f == NULL || dispatch_get_main_queue == NULL) { + #else + *(void **) (&dispatch_sync_f_f) = dlsym(RTLD_DEFAULT, "dispatch_sync_f"); + const char *dlError = dlerror(); + if (dlError != NULL) { + logger(LOG_LEVEL_DEBUG, "%s [%u]: %s.\n", + __FUNCTION__, __LINE__, dlError); + } + + *(void **) (&dispatch_get_main_queue_f) = dlsym(RTLD_DEFAULT, "dispatch_get_main_queue"); + dlError = dlerror(); + if (dlError != NULL) { + logger(LOG_LEVEL_DEBUG, "%s [%u]: %s.\n", + __FUNCTION__, __LINE__, dlError); + } + + if (dispatch_sync_f_f == NULL || dispatch_get_main_queue_f == NULL) { + #endif + logger(LOG_LEVEL_DEBUG, "%s [%u]: Failed to locate dispatch_sync_f() or dispatch_get_main_queue()!\n", + __FUNCTION__, __LINE__); + + #if ! defined(USE_CARBON_LEGACY) && defined(USE_COREFOUNDATION) + logger(LOG_LEVEL_DEBUG, "%s [%u]: Falling back to runloop signaling.\n", + __FUNCTION__, __LINE__); + + int runloop_status = start_message_port_runloop(); + if (runloop_status != IOHOOK_SUCCESS) { + return runloop_status; + } + #endif + } + } + + // Add the event source and observer to the runloop mode. + CFRunLoopAddSource(event_loop, hook->source, kCFRunLoopDefaultMode); + CFRunLoopAddObserver(event_loop, hook->observer, kCFRunLoopDefaultMode); + + #ifdef USE_OBJC + // Create a garbage collector to handle Cocoa events correctly. + Class NSAutoreleasePool_class = (Class) objc_getClass("NSAutoreleasePool"); + id pool = class_createInstance(NSAutoreleasePool_class, 0); + auto_release_pool = objc_msgSend(pool, sel_registerName("init")); + #endif + + // Start the hook thread runloop. + CFRunLoopRun(); + + + #ifdef USE_OBJC + //objc_msgSend(auto_release_pool, sel_registerName("drain")); + objc_msgSend(auto_release_pool, sel_registerName("release")); + #endif + + // Lock back up until we are done processing the exit. + if (CFRunLoopContainsObserver(event_loop, hook->observer, kCFRunLoopDefaultMode)) { + CFRunLoopRemoveObserver(event_loop, hook->observer, kCFRunLoopDefaultMode); + } + + if (CFRunLoopContainsSource(event_loop, hook->source, kCFRunLoopDefaultMode)) { + CFRunLoopRemoveSource(event_loop, hook->source, kCFRunLoopDefaultMode); + } + + #if ! defined(USE_CARBON_LEGACY) && defined(USE_COREFOUNDATION) + if (! CFEqual(event_loop, CFRunLoopGetMain())) { + #ifdef USE_WEAK_IMPORT + if (dispatch_sync_f == NULL || dispatch_get_main_queue == NULL) { + #else + if (dispatch_sync_f_f == NULL || dispatch_get_main_queue_f == NULL) { + #endif + stop_message_port_runloop(); + } + } + #endif + + // Free the TIS Message. + free(tis_message); + } + else { + logger(LOG_LEVEL_ERROR, "%s [%u]: Failed to allocate memory for TIS message structure!\n", + __FUNCTION__, __LINE__); + + // Set the exit status. + status = IOHOOK_ERROR_OUT_OF_MEMORY; + } + + // Invalidate and free hook observer. + CFRunLoopObserverInvalidate(hook->observer); + CFRelease(hook->observer); + } + else { + // We cant do a whole lot of anything if we cant + // create run loop observer. + logger(LOG_LEVEL_ERROR, "%s [%u]: CFRunLoopObserverCreate failure!\n", + __FUNCTION__, __LINE__); + + // Set the exit status. + status = IOHOOK_ERROR_CREATE_OBSERVER; + } + } + else { + logger(LOG_LEVEL_ERROR, "%s [%u]: CFRunLoopGetCurrent failure!\n", + __FUNCTION__, __LINE__); + + // Set the exit status. + status = IOHOOK_ERROR_GET_RUNLOOP; + } + + // Clean up the event source. + CFRelease(hook->source); + } + else { + logger(LOG_LEVEL_ERROR, "%s [%u]: CFMachPortCreateRunLoopSource failure!\n", + __FUNCTION__, __LINE__); + + // Set the exit status. + status = IOHOOK_ERROR_CREATE_RUN_LOOP_SOURCE; + } + + // Stop the CFMachPort from receiving any more messages. + CFMachPortInvalidate(hook->port); + CFRelease(hook->port); + } + else { + logger(LOG_LEVEL_ERROR, "%s [%u]: Failed to create event port!\n", + __FUNCTION__, __LINE__); + + // Set the exit status. + status = IOHOOK_ERROR_CREATE_EVENT_PORT; + } + + // Free the hook structure. + free(hook); + } + else { + status = IOHOOK_ERROR_OUT_OF_MEMORY; + } + } + else { + logger(LOG_LEVEL_ERROR, "%s [%u]: Accessibility API is disabled!\n", + __FUNCTION__, __LINE__); + + // Set the exit status. + status = IOHOOK_ERROR_AXAPI_DISABLED; + } + } while (restart_tap); + + logger(LOG_LEVEL_DEBUG, "%s [%u]: Something, something, something, complete.\n", + __FUNCTION__, __LINE__); + + return status; +} + +IOHOOK_API int hook_stop() { + int status = IOHOOK_FAILURE; + + CFStringRef mode = CFRunLoopCopyCurrentMode(event_loop); + if (mode != NULL) { + CFRelease(mode); + + // Make sure the tap doesn't restart. + restart_tap = false; + + // Stop the run loop. + CFRunLoopStop(event_loop); + + status = IOHOOK_SUCCESS; + } + + logger(LOG_LEVEL_DEBUG, "%s [%u]: Status: %#X.\n", + __FUNCTION__, __LINE__, status); + + return status; +} diff --git a/vendor/github.com/robotn/gohook/hook/darwin/input.h b/vendor/github.com/robotn/gohook/hook/darwin/input.h new file mode 100644 index 0000000..a841070 --- /dev/null +++ b/vendor/github.com/robotn/gohook/hook/darwin/input.h @@ -0,0 +1,103 @@ + +#ifndef _included_input_helper +#define _included_input_helper + +#include +#include // For HIToolbox kVK_ keycodes and TIS funcitons. +#ifdef USE_IOKIT +#include +#endif +#include + + +#ifndef USE_IOKIT +// Some of the system key codes that are needed from IOKit. +#define NX_KEYTYPE_SOUND_UP 0x00 +#define NX_KEYTYPE_SOUND_DOWN 0x01 +#define NX_KEYTYPE_MUTE 0x07 + +/* Display controls... +#define NX_KEYTYPE_BRIGHTNESS_UP 0x02 +#define NX_KEYTYPE_BRIGHTNESS_DOWN 0x03 +#define NX_KEYTYPE_CONTRAST_UP 0x0B +#define NX_KEYTYPE_CONTRAST_DOWN 0x0C +#define NX_KEYTYPE_ILLUMINATION_UP 0x15 +#define NX_KEYTYPE_ILLUMINATION_DOWN 0x16 +#define NX_KEYTYPE_ILLUMINATION_TOGGLE 0x17 +*/ + +#define NX_KEYTYPE_CAPS_LOCK 0x04 +//#define NX_KEYTYPE_HELP 0x05 +#define NX_POWER_KEY 0x06 + +#define NX_KEYTYPE_EJECT 0x0E +#define NX_KEYTYPE_PLAY 0x10 +#define NX_KEYTYPE_NEXT 0x12 +#define NX_KEYTYPE_PREVIOUS 0x13 + +/* There is no official fast-forward or rewind scan code support.*/ +#define NX_KEYTYPE_FAST 0x14 +#define NX_KEYTYPE_REWIND 0x15 + +#endif + +// These virtual key codes do not appear to be defined anywhere by Apple. +#define kVK_NX_Power 0xE0 | NX_POWER_KEY /* 0xE6 */ +#define kVK_NX_Eject 0xE0 | NX_KEYTYPE_EJECT /* 0xEE */ + +#define kVK_MEDIA_Play 0xE0 | NX_KEYTYPE_PLAY /* 0xF0 */ +#define kVK_MEDIA_Next 0xE0 | NX_KEYTYPE_NEXT /* 0xF1 */ +#define kVK_MEDIA_Previous 0xE0 | NX_KEYTYPE_PREVIOUS /* 0xF2 */ + +#define kVK_RightCommand 0x36 +#define kVK_ContextMenu 0x6E // AKA kMenuPowerGlyph +#define kVK_Undefined 0xFF + +// These button codes do not appear to be defined anywhere by Apple. +#define kVK_LBUTTON kCGMouseButtonLeft +#define kVK_RBUTTON kCGMouseButtonRight +#define kVK_MBUTTON kCGMouseButtonCenter +#define kVK_XBUTTON1 3 +#define kVK_XBUTTON2 4 + +// These button masks do not appear to be defined anywhere by Apple. +#define kCGEventFlagMaskButtonLeft 1 << 0 +#define kCGEventFlagMaskButtonRight 1 << 1 +#define kCGEventFlagMaskButtonCenter 1 << 2 +#define kCGEventFlagMaskXButton1 1 << 3 +#define kCGEventFlagMaskXButton2 1 << 4 + + +/* Check for access to Apples accessibility API. + */ +extern bool is_accessibility_enabled(); + +/* Converts an OSX key code and event mask to the appropriate Unicode character + * representation. + */ +extern UniCharCount keycode_to_unicode(CGEventRef event_ref, UniChar *buffer, UniCharCount size); + +/* Converts an OSX keycode to the appropriate IOHook scancode constant. + */ +extern uint16_t keycode_to_scancode(UInt64 keycode); + +/* Converts a IOHook scancode constant to the appropriate OSX keycode. + */ +extern UInt64 scancode_to_keycode(uint16_t keycode); + + +/* Initialize items required for KeyCodeToKeySym() and KeySymToUnicode() + * functionality. This method is called by OnLibraryLoad() and may need to be + * called in combination with UnloadInputHelper() if the native keyboard layout + * is changed. + */ +extern void load_input_helper(); + +/* De-initialize items required for KeyCodeToKeySym() and KeySymToUnicode() + * functionality. This method is called by OnLibraryUnload() and may need to be + * called in combination with LoadInputHelper() if the native keyboard layout + * is changed. + */ +extern void unload_input_helper(); + +#endif diff --git a/vendor/github.com/robotn/gohook/hook/darwin/input_c.h b/vendor/github.com/robotn/gohook/hook/darwin/input_c.h new file mode 100644 index 0000000..298f67f --- /dev/null +++ b/vendor/github.com/robotn/gohook/hook/darwin/input_c.h @@ -0,0 +1,542 @@ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#ifdef USE_COREFOUNDATION + #include +#endif +#ifndef USE_WEAK_IMPORT + #include +#endif + +#include +#include "input.h" +#include "../iohook.h" +#include "../logger_c.h" + +// Current dead key state. +#if defined(USE_CARBON_LEGACY) || defined(USE_COREFOUNDATION) +static UInt32 deadkey_state; +#endif + +// Input source data for the keyboard. +#if defined(USE_CARBON_LEGACY) +static KeyboardLayoutRef prev_keyboard_layout = NULL; +#elif defined(USE_COREFOUNDATION) +static TISInputSourceRef prev_keyboard_layout = NULL; +#endif + +#ifdef USE_WEAK_IMPORT +// Required to dynamically check for AXIsProcessTrustedWithOptions availability. +extern Boolean AXIsProcessTrustedWithOptions(CFDictionaryRef options) __attribute__((weak_import)); +extern CFStringRef kAXTrustedCheckOptionPrompt __attribute__((weak_import)); +#else +static Boolean (*AXIsProcessTrustedWithOptions_t)(CFDictionaryRef); +#endif + +bool is_accessibility_enabled() { + bool is_enabled = false; + + #ifdef USE_WEAK_IMPORT + // Check and make sure assistive devices is enabled. + if (AXIsProcessTrustedWithOptions != NULL) { + // New accessibility API 10.9 and later. + const void * keys[] = { kAXTrustedCheckOptionPrompt }; + const void * values[] = { kCFBooleanTrue }; + + CFDictionaryRef options = CFDictionaryCreate( + kCFAllocatorDefault, + keys, + values, + sizeof(keys) / sizeof(*keys), + &kCFCopyStringDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks); + + is_enabled = AXIsProcessTrustedWithOptions(options); + } + #else + // Dynamically load the application services framework for examination. + *(void **) (&AXIsProcessTrustedWithOptions_t) = dlsym(RTLD_DEFAULT, "AXIsProcessTrustedWithOptions"); + const char *dlError = dlerror(); + if (AXIsProcessTrustedWithOptions_t != NULL && dlError == NULL) { + // Check for property CFStringRef kAXTrustedCheckOptionPrompt + void ** kAXTrustedCheckOptionPrompt_t = dlsym(RTLD_DEFAULT, "kAXTrustedCheckOptionPrompt"); + + dlError = dlerror(); + if (kAXTrustedCheckOptionPrompt_t != NULL && dlError == NULL) { + // New accessibility API 10.9 and later. + const void * keys[] = { *kAXTrustedCheckOptionPrompt_t }; + const void * values[] = { kCFBooleanTrue }; + + CFDictionaryRef options = CFDictionaryCreate( + kCFAllocatorDefault, + keys, + values, + sizeof(keys) / sizeof(*keys), + &kCFCopyStringDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks); + + is_enabled = (*AXIsProcessTrustedWithOptions_t)(options); + } + } + #endif + else { + #ifndef USE_WEAK_IMPORT + if (dlError != NULL) { + // Could not load the AXIsProcessTrustedWithOptions function! + logger(LOG_LEVEL_DEBUG, "%s [%u]: %s.\n", + __FUNCTION__, __LINE__, dlError); + } + #endif + + logger(LOG_LEVEL_DEBUG, "%s [%u]: Weak import AXIsProcessTrustedWithOptions not found.\n", + __FUNCTION__, __LINE__, dlError); + + logger(LOG_LEVEL_DEBUG, "%s [%u]: Falling back to AXAPIEnabled().\n", + __FUNCTION__, __LINE__, dlError); + + // Old accessibility check 10.8 and older. + is_enabled = AXAPIEnabled(); + } + + return is_enabled; +} + + +UniCharCount keycode_to_unicode(CGEventRef event_ref, UniChar *buffer, UniCharCount size) { + UniCharCount count = 0; + + #if defined(USE_CARBON_LEGACY) + KeyboardLayoutRef curr_keyboard_layout; + void *inputData = NULL; + if (KLGetCurrentKeyboardLayout(&curr_keyboard_layout) == noErr) { + if (KLGetKeyboardLayoutProperty(curr_keyboard_layout, kKLuchrData, (const void **) &inputData) != noErr) { + inputData = NULL; + } + } + #elif defined(USE_COREFOUNDATION) + CFDataRef inputData = NULL; + if (CFEqual(CFRunLoopGetCurrent(), CFRunLoopGetMain())) { + // NOTE The following block must execute on the main runloop, + // Ex: CFEqual(CFRunLoopGetCurrent(), CFRunLoopGetMain()) to avoid + // Exception detected while handling key input and TSMProcessRawKeyCode failed + // (-192) errors. + TISInputSourceRef curr_keyboard_layout = TISCopyCurrentKeyboardLayoutInputSource(); + if (curr_keyboard_layout != NULL && CFGetTypeID(curr_keyboard_layout) == TISInputSourceGetTypeID()) { + CFDataRef data = (CFDataRef) TISGetInputSourceProperty(curr_keyboard_layout, kTISPropertyUnicodeKeyLayoutData); + if (data != NULL && CFGetTypeID(data) == CFDataGetTypeID() && CFDataGetLength(data) > 0) { + inputData = (CFDataRef) data; + } + } + + // Check if the keyboard layout has changed to see if the dead key state needs to be discarded. + if (prev_keyboard_layout != NULL && curr_keyboard_layout != NULL && CFEqual(curr_keyboard_layout, prev_keyboard_layout) == false) { + deadkey_state = 0x00; + } + + // Release the previous keyboard layout. + if (prev_keyboard_layout != NULL) { + CFRelease(prev_keyboard_layout); + prev_keyboard_layout = NULL; + } + + // Set the previous keyboard layout to the current layout. + if (curr_keyboard_layout != NULL) { + prev_keyboard_layout = curr_keyboard_layout; + } + } + #endif + + #if defined(USE_CARBON_LEGACY) || defined(USE_COREFOUNDATION) + if (inputData != NULL) { + #ifdef USE_CARBON_LEGACY + const UCKeyboardLayout *keyboard_layout = (const UCKeyboardLayout *) inputData; + #else + const UCKeyboardLayout *keyboard_layout = (const UCKeyboardLayout*) CFDataGetBytePtr(inputData); + #endif + + if (keyboard_layout != NULL) { + //Extract keycode and modifier information. + CGKeyCode keycode = CGEventGetIntegerValueField(event_ref, kCGKeyboardEventKeycode); + CGEventFlags modifiers = CGEventGetFlags(event_ref); + + // Disable all command modifiers for translation. This is required + // so UCKeyTranslate will provide a keysym for the separate event. + static const CGEventFlags cmd_modifiers = kCGEventFlagMaskCommand | + kCGEventFlagMaskControl | kCGEventFlagMaskAlternate; + modifiers &= ~cmd_modifiers; + + // I don't know why but UCKeyTranslate does not process the + // kCGEventFlagMaskAlphaShift (A.K.A. Caps Lock Mask) correctly. + // We need to basically turn off the mask and process the capital + // letters after UCKeyTranslate(). + bool is_caps_lock = modifiers & kCGEventFlagMaskAlphaShift; + modifiers &= ~kCGEventFlagMaskAlphaShift; + + // Run the translation with the saved deadkey_state. + OSStatus status = UCKeyTranslate( + keyboard_layout, + keycode, + kUCKeyActionDown, //kUCKeyActionDisplay, + (modifiers >> 16) & 0xFF, //(modifiers >> 16) & 0xFF, || (modifiers >> 8) & 0xFF, + LMGetKbdType(), + kNilOptions, //kNilOptions, //kUCKeyTranslateNoDeadKeysMask + &deadkey_state, + size, + &count, + buffer); + + if (status == noErr && count > 0) { + if (is_caps_lock) { + // We *had* a caps lock mask so we need to convert to uppercase. + CFMutableStringRef keytxt = CFStringCreateMutableWithExternalCharactersNoCopy(kCFAllocatorDefault, buffer, count, size, kCFAllocatorNull); + if (keytxt != NULL) { + CFLocaleRef locale = CFLocaleCopyCurrent(); + CFStringUppercase(keytxt, locale); + CFRelease(locale); + CFRelease(keytxt); + } + else { + // There was an problem creating the CFMutableStringRef. + count = 0; + } + } + } + else { + // Make sure the buffer count is zero if an error occurred. + count = 0; + } + } + } + #else + CGEventKeyboardGetUnicodeString(event_ref, size, &count, buffer); + #endif + + // The following codes should not be processed because they are invalid. + if (count == 1) { + switch (buffer[0]) { + case 0x01: // Home + case 0x04: // End + case 0x05: // Help Key + case 0x10: // Function Keys + case 0x0B: // Page Up + case 0x0C: // Page Down + case 0x1F: // Volume Up + count = 0; + } + } + + return count; +} + + +static const uint16_t keycode_scancode_table[][2] = { + /* idx { keycode, scancode }, */ + /* 0 */ { VC_A, kVK_Undefined }, // 0x00 + /* 1 */ { VC_S, kVK_Escape }, // 0x01 + /* 2 */ { VC_D, kVK_ANSI_1 }, // 0x02 + /* 3 */ { VC_F, kVK_ANSI_2 }, // 0x03 + /* 4 */ { VC_H, kVK_ANSI_3 }, // 0x04 + /* 5 */ { VC_G, kVK_ANSI_4 }, // 0x05 + /* 6 */ { VC_Z, kVK_ANSI_5 }, // 0x07 + /* 7 */ { VC_X, kVK_ANSI_6 }, // 0x08 + /* 8 */ { VC_C, kVK_ANSI_7 }, // 0x09 + /* 9 */ { VC_V, kVK_ANSI_8 }, // 0x0A + /* 10 */ { VC_UNDEFINED, kVK_ANSI_9 }, // 0x0B + /* 11 */ { VC_B, kVK_ANSI_0 }, // 0x0C + /* 12 */ { VC_Q, kVK_ANSI_Minus }, // 0x0D + /* 13 */ { VC_W, kVK_ANSI_Equal }, // 0x0E + /* 14 */ { VC_E, kVK_Delete }, // 0x0F + /* 15 */ { VC_R, kVK_Tab }, // 0x10 + /* 16 */ { VC_Y, kVK_ANSI_Q }, // 0x11 + /* 17 */ { VC_T, kVK_ANSI_W }, // 0x12 + /* 18 */ { VC_1, kVK_ANSI_E }, // 0x13 + /* 19 */ { VC_2, kVK_ANSI_R }, // 0x14 + /* 20 */ { VC_3, kVK_ANSI_T }, // 0x15 + /* 21 */ { VC_4, kVK_ANSI_Y }, // 0x16 + /* 22 */ { VC_6, kVK_ANSI_U }, // 0x17 + /* 23 */ { VC_5, kVK_ANSI_I }, // 0x18 + /* 24 */ { VC_EQUALS, kVK_ANSI_O }, // 0x19 + /* 25 */ { VC_9, kVK_ANSI_P }, // 0x19 + /* 26 */ { VC_7, kVK_ANSI_LeftBracket }, // 0x1A + /* 27 */ { VC_MINUS, kVK_ANSI_RightBracket }, // 0x1B + /* 28 */ { VC_8, kVK_Return }, // 0x1C + /* 29 */ { VC_0, kVK_Control }, // 0x1D + /* 30 */ { VC_CLOSE_BRACKET, kVK_ANSI_A }, // 0x1E + /* 31 */ { VC_O, kVK_ANSI_S }, // 0x1F + /* 32 */ { VC_U, kVK_ANSI_D }, // 0x20 + /* 33 */ { VC_OPEN_BRACKET, kVK_ANSI_F }, // 0x21 + /* 34 */ { VC_I, kVK_ANSI_G }, // 0x22 + /* 35 */ { VC_P, kVK_ANSI_H }, // 0x23 + /* 36 */ { VC_ENTER, kVK_ANSI_J }, // 0x24 + /* 37 */ { VC_L, kVK_ANSI_K }, // 0x25 + /* 38 */ { VC_J, kVK_ANSI_L }, // 0x26 + /* 39 */ { VC_QUOTE, kVK_ANSI_Semicolon }, // 0x27 + /* 40 */ { VC_K, kVK_ANSI_Quote }, // 0x28 + /* 41 */ { VC_SEMICOLON, kVK_ANSI_Grave }, // 0x29 + /* 42 */ { VC_BACK_SLASH, kVK_Shift }, // 0x2A + /* 43 */ { VC_COMMA, kVK_ANSI_Backslash }, // 0x2B + /* 44 */ { VC_SLASH, kVK_ANSI_Z }, // 0x2C + /* 45 */ { VC_N, kVK_ANSI_X }, // 0x2D + /* 46 */ { VC_M, kVK_ANSI_C }, // 0x2E + /* 47 */ { VC_PERIOD, kVK_ANSI_V }, // 0x2F + /* 48 */ { VC_TAB, kVK_ANSI_B }, // 0x30 + /* 49 */ { VC_SPACE, kVK_ANSI_N }, // 0x31 + /* 50 */ { VC_BACKQUOTE, kVK_ANSI_M }, // 0x32 + /* 51 */ { VC_BACKSPACE, kVK_ANSI_Comma }, // 0x33 + /* 52 */ { VC_UNDEFINED, kVK_ANSI_Period }, // 0x34 + /* 53 */ { VC_ESCAPE, kVK_ANSI_Slash }, // 0x35 + /* 54 */ { VC_META_R, kVK_RightShift }, // 0x36 + /* 55 */ { VC_META_L, kVK_ANSI_KeypadMultiply }, // 0x37 + /* 56 */ { VC_SHIFT_L, kVK_Option }, // 0x38 + /* 57 */ { VC_CAPS_LOCK, kVK_Space }, // 0x39 + /* 58 */ { VC_ALT_L, kVK_CapsLock }, // 0x3A + /* 59 */ { VC_CONTROL_L, kVK_F1 }, // 0x3B + /* 60 */ { VC_SHIFT_R, kVK_F2 }, // 0x3C + /* 61 */ { VC_ALT_R, kVK_F3 }, // 0x3D + /* 62 */ { VC_CONTROL_R, kVK_F4 }, // 0x3E + /* 63 */ { VC_UNDEFINED, kVK_F5 }, // 0x3F + /* 64 */ { VC_F17, kVK_F6 }, // 0x40 + /* 65 */ { VC_KP_SEPARATOR, kVK_F7 }, // 0x41 + /* 66 */ { VC_UNDEFINED, kVK_F8 }, // 0x42 + /* 67 */ { VC_KP_MULTIPLY, kVK_F9 }, // 0x43 + /* 68 */ { VC_UNDEFINED, kVK_F10 }, // 0x44 + /* 69 */ { VC_KP_ADD, kVK_ANSI_KeypadClear }, // 0x45 + /* 70 */ { VC_UNDEFINED, kVK_Undefined }, // 0x46 + /* 71 */ { VC_NUM_LOCK, kVK_ANSI_Keypad7 }, // 0x47 + /* 72 */ { VC_VOLUME_UP, kVK_ANSI_Keypad8 }, // 0x48 + /* 73 */ { VC_VOLUME_DOWN, kVK_ANSI_Keypad9 }, // 0x49 + /* 74 */ { VC_VOLUME_MUTE, kVK_ANSI_KeypadMinus }, // 0x4A + /* 75 */ { VC_KP_DIVIDE, kVK_ANSI_Keypad4 }, // 0x4B + /* 76 */ { VC_KP_ENTER, kVK_ANSI_Keypad5 }, // 0x4C + /* 77 */ { VC_UNDEFINED, kVK_ANSI_Keypad6 }, // 0x4D + /* 78 */ { VC_KP_SUBTRACT, kVK_ANSI_KeypadPlus }, // 0x4E + /* 79 */ { VC_F18, kVK_ANSI_Keypad1 }, // 0x4F + /* 80 */ { VC_F19, kVK_ANSI_Keypad2 }, // 0x50 + /* 81 */ { VC_KP_EQUALS, kVK_ANSI_Keypad3 }, // 0x51 + /* 82 */ { VC_KP_0, kVK_ANSI_Keypad0 }, // 0x52 + /* 83 */ { VC_KP_1, kVK_ANSI_KeypadDecimal }, // 0x53 + /* 84 */ { VC_KP_2, kVK_Undefined }, // 0x54 + /* 85 */ { VC_KP_3, kVK_Undefined }, // 0x55 + /* 86 */ { VC_KP_4, kVK_Undefined }, // 0x56 + /* 87 */ { VC_KP_5, kVK_F11 }, // 0x57 + /* 88 */ { VC_KP_6, kVK_F12 }, // 0x58 + /* 89 */ { VC_KP_7, kVK_Undefined }, // 0x59 + /* 90 */ { VC_F20, kVK_Undefined }, // 0x5A + /* 91 */ { VC_KP_8, kVK_F13 }, // 0x5B + /* 92 */ { VC_KP_9, kVK_F14 }, // 0x5C + /* 93 */ { VC_YEN, kVK_F15 }, // 0x5D + /* 94 */ { VC_UNDERSCORE, kVK_Undefined }, // 0x5E + /* 95 */ { VC_KP_COMMA, kVK_Undefined }, // 0x5F + /* 96 */ { VC_F5, kVK_Undefined }, // 0x60 + /* 97 */ { VC_F6, kVK_Undefined }, // 0x61 + /* 98 */ { VC_F7, kVK_Undefined }, // 0x62 + /* 99 */ { VC_F3, kVK_F16 }, // 0x63 + /* 100 */ { VC_F8, kVK_F17 }, // 0x64 + /* 101 */ { VC_F9, kVK_F18 }, // 0x65 + /* 102 */ { VC_UNDEFINED, kVK_F19 }, // 0x66 + /* 103 */ { VC_F11, kVK_F20 }, // 0x67 + /* 104 */ { VC_KATAKANA, kVK_Undefined }, // 0x68 + /* 105 */ { VC_F13, kVK_Undefined }, // 0x69 + /* 106 */ { VC_F16, kVK_Undefined }, // 0x6A + /* 107 */ { VC_F14, kVK_Undefined }, // 0x6B + /* 108 */ { VC_UNDEFINED, kVK_Undefined }, // 0x6C FIXME kVK_JIS_Eisu same as Caps Lock ? + /* 109 */ { VC_F10, kVK_Undefined }, // 0x6D + /* 110 */ { VC_UNDEFINED, kVK_Undefined }, // 0x6E + /* 111 */ { VC_F12, kVK_Undefined }, // 0x6F + /* 112 */ { VC_UNDEFINED, kVK_JIS_Kana }, // 0x70 + /* 113 */ { VC_F15, kVK_Undefined }, // 0x71 + /* 114 */ { VC_INSERT, kVK_Undefined }, // 0x72 + /* 115 */ { VC_HOME, kVK_JIS_Underscore }, // 0x73 + /* 116 */ { VC_PAGE_UP, kVK_Undefined }, // 0x74 + /* 117 */ { VC_DELETE, kVK_Undefined }, // 0x75 + /* 118 */ { VC_F4, kVK_Undefined }, // 0x76 + /* 119 */ { VC_END, kVK_Undefined }, // 0x77 + /* 120 */ { VC_F2, kVK_Undefined }, // 0x78 + /* 121 */ { VC_PAGE_DOWN, kVK_Undefined }, // 0x79 + /* 122 */ { VC_F1, kVK_Undefined }, // 0x7A + /* 123 */ { VC_LEFT, kVK_Undefined }, // 0x7B + /* 124 */ { VC_RIGHT, kVK_Undefined }, // 0x7C + /* 125 */ { VC_DOWN, kVK_JIS_Yen }, // 0x7D + /* 126 */ { VC_UP, kVK_JIS_KeypadComma }, // 0x7E + /* 127 */ { VC_UNDEFINED, kVK_Undefined }, // 0x7F + + // No Offset Offset (i & 0x007F) + 128 + + /* 128 */ { VC_UNDEFINED, kVK_Undefined }, // 0x80 + /* 129 */ { VC_UNDEFINED, kVK_Undefined }, // 0x81 + /* 130 */ { VC_UNDEFINED, kVK_Undefined }, // 0x82 + /* 131 */ { VC_UNDEFINED, kVK_Undefined }, // 0x83 + /* 132 */ { VC_UNDEFINED, kVK_Undefined }, // 0x84 + /* 133 */ { VC_UNDEFINED, kVK_Undefined }, // 0x85 + /* 134 */ { VC_UNDEFINED, kVK_Undefined }, // 0x86 + /* 135 */ { VC_UNDEFINED, kVK_Undefined }, // 0x87 + /* 136 */ { VC_UNDEFINED, kVK_Undefined }, // 0x88 + /* 137 */ { VC_UNDEFINED, kVK_Undefined }, // 0x89 + /* 138 */ { VC_UNDEFINED, kVK_Undefined }, // 0x8A + /* 139 */ { VC_UNDEFINED, kVK_Undefined }, // 0x8B + /* 140 */ { VC_UNDEFINED, kVK_Undefined }, // 0x8C + /* 141 */ { VC_UNDEFINED, kVK_ANSI_KeypadEquals }, // 0x8D + /* 142 */ { VC_UNDEFINED, kVK_Undefined }, // 0x8E + /* 143 */ { VC_UNDEFINED, kVK_Undefined }, // 0x8F + /* 144 */ { VC_UNDEFINED, kVK_MEDIA_Previous }, // 0x90 + /* 145 */ { VC_UNDEFINED, kVK_Undefined }, // 0x91 + /* 146 */ { VC_UNDEFINED, kVK_Undefined }, // 0x92 + /* 147 */ { VC_UNDEFINED, kVK_Undefined }, // 0x93 + /* 148 */ { VC_UNDEFINED, kVK_Undefined }, // 0x94 + /* 149 */ { VC_UNDEFINED, kVK_Undefined }, // 0x95 + /* 150 */ { VC_UNDEFINED, kVK_Undefined }, // 0x96 + /* 151 */ { VC_UNDEFINED, kVK_Undefined }, // 0x97 + /* 152 */ { VC_UNDEFINED, kVK_Undefined }, // 0x98 + /* 153 */ { VC_UNDEFINED, kVK_MEDIA_Next }, // 0x99 + /* 154 */ { VC_UNDEFINED, kVK_Undefined }, // 0x9A + /* 155 */ { VC_UNDEFINED, kVK_Undefined }, // 0x9B + /* 156 */ { VC_UNDEFINED, kVK_ANSI_KeypadEnter }, // 0x9C + /* 157 */ { VC_UNDEFINED, kVK_RightControl }, // 0x9D + /* 158 */ { VC_UNDEFINED, kVK_Undefined }, // 0x9E + /* 159 */ { VC_UNDEFINED, kVK_Undefined }, // 0x9F + /* 160 */ { VC_UNDEFINED, kVK_Mute }, // 0xA0 + /* 161 */ { VC_UNDEFINED, kVK_Undefined }, // 0xA1 + /* 162 */ { VC_UNDEFINED, kVK_MEDIA_Play }, // 0xA2 + /* 163 */ { VC_UNDEFINED, kVK_Undefined }, // 0xA3 + /* 164 */ { VC_UNDEFINED, kVK_Undefined }, // 0xA4 + /* 165 */ { VC_UNDEFINED, kVK_Undefined }, // 0xA5 + /* 166 */ { VC_UNDEFINED, kVK_Undefined }, // 0xA6 + /* 167 */ { VC_UNDEFINED, kVK_Undefined }, // 0xA7 + /* 168 */ { VC_UNDEFINED, kVK_Undefined }, // 0xA8 + /* 169 */ { VC_UNDEFINED, kVK_Undefined }, // 0xA9 + /* 170 */ { VC_UNDEFINED, kVK_Undefined }, // 0xAA + /* 171 */ { VC_UNDEFINED, kVK_Undefined }, // 0xAB + /* 172 */ { VC_UNDEFINED, kVK_NX_Eject }, // 0xAC + /* 173 */ { VC_UNDEFINED, kVK_Undefined }, // 0xAD + /* 174 */ { VC_UNDEFINED, kVK_VolumeDown }, // 0xAE + /* 175 */ { VC_UNDEFINED, kVK_Undefined }, // 0xAF + /* 176 */ { VC_UNDEFINED, kVK_VolumeUp }, // 0xB0 + /* 177 */ { VC_UNDEFINED, kVK_Undefined }, // 0xB1 + /* 178 */ { VC_UNDEFINED, kVK_Undefined }, // 0xB2 + /* 179 */ { VC_UNDEFINED, kVK_Undefined }, // 0xB3 + /* 180 */ { VC_UNDEFINED, kVK_Undefined }, // 0xB4 + /* 181 */ { VC_UNDEFINED, kVK_ANSI_KeypadDivide }, // 0xB5 + /* 182 */ { VC_UNDEFINED, kVK_Undefined }, // 0xB6 + /* 183 */ { VC_UNDEFINED, kVK_Undefined }, // 0xB7 + /* 184 */ { VC_UNDEFINED, kVK_RightOption }, // 0xB8 + /* 185 */ { VC_UNDEFINED, kVK_Undefined }, // 0xB9 + /* 186 */ { VC_UNDEFINED, kVK_Undefined }, // 0xBA + /* 187 */ { VC_UNDEFINED, kVK_Undefined }, // 0xBB + /* 188 */ { VC_UNDEFINED, kVK_Undefined }, // 0xBC + /* 189 */ { VC_UNDEFINED, kVK_Undefined }, // 0xBD + /* 190 */ { VC_UNDEFINED, kVK_Undefined }, // 0xBE + /* 191 */ { VC_UNDEFINED, kVK_Undefined }, // 0xBF + /* 192 */ { VC_UNDEFINED, kVK_Undefined }, // 0xC0 + /* 193 */ { VC_UNDEFINED, kVK_Undefined }, // 0xC1 + /* 194 */ { VC_UNDEFINED, kVK_Undefined }, // 0xC2 + /* 195 */ { VC_UNDEFINED, kVK_Undefined }, // 0xC3 + /* 196 */ { VC_UNDEFINED, kVK_Undefined }, // 0xC4 + /* 197 */ { VC_UNDEFINED, kVK_Undefined }, // 0xC5 + /* 198 */ { VC_UNDEFINED, kVK_Undefined }, // 0xC6 + /* 199 */ { VC_UNDEFINED, kVK_Home }, // 0xC7 + /* 200 */ { VC_UNDEFINED, kVK_UpArrow }, // 0xC8 + /* 201 */ { VC_UNDEFINED, kVK_PageUp }, // 0xC9 + /* 202 */ { VC_UNDEFINED, kVK_Undefined }, // 0xCA + /* 203 */ { VC_UNDEFINED, kVK_LeftArrow }, // 0xCB + /* 204 */ { VC_UNDEFINED, kVK_Undefined }, // 0xCC + /* 205 */ { VC_UNDEFINED, kVK_RightArrow }, // 0xCD + /* 206 */ { VC_UNDEFINED, kVK_Undefined }, // 0xCE + /* 207 */ { VC_UNDEFINED, kVK_End }, // 0xCF + /* 208 */ { VC_UNDEFINED, kVK_DownArrow }, // 0xD0 + /* 209 */ { VC_UNDEFINED, kVK_PageDown }, // 0xD1 + /* 210 */ { VC_UNDEFINED, kVK_Help }, // 0xD2 + /* 211 */ { VC_UNDEFINED, kVK_ForwardDelete }, // 0xD3 + /* 212 */ { VC_UNDEFINED, kVK_Undefined }, // 0xD4 + /* 213 */ { VC_UNDEFINED, kVK_Undefined }, // 0xD5 + /* 214 */ { VC_UNDEFINED, kVK_Undefined }, // 0xD6 + /* 215 */ { VC_UNDEFINED, kVK_Undefined }, // 0xD7 + /* 216 */ { VC_UNDEFINED, kVK_Undefined }, // 0xD8 + /* 217 */ { VC_UNDEFINED, kVK_Undefined }, // 0xD9 + /* 218 */ { VC_UNDEFINED, kVK_Undefined }, // 0xDA + /* 219 */ { VC_UNDEFINED, kVK_Command }, // 0xDB + /* 220 */ { VC_UNDEFINED, kVK_RightCommand }, // 0xDC + /* 221 */ { VC_UNDEFINED, kVK_Undefined }, // 0xDD + /* 222 */ { VC_UNDEFINED, kVK_NX_Power }, // 0xDE + /* 223 */ { VC_UNDEFINED, kVK_Undefined }, // 0xDF + /* 224 */ { VC_UNDEFINED, kVK_Undefined }, // 0xE0 + /* 225 */ { VC_UNDEFINED, kVK_Undefined }, // 0xE1 + /* 226 */ { VC_UNDEFINED, kVK_Undefined }, // 0xE2 + /* 227 */ { VC_UNDEFINED, kVK_Undefined }, // 0xE3 + /* 228 */ { VC_UNDEFINED, kVK_Undefined }, // 0xE4 + /* 229 */ { VC_UNDEFINED, kVK_Undefined }, // 0xE5 + /* 230 */ { VC_POWER, kVK_Undefined }, // 0xE6 + /* 231 */ { VC_UNDEFINED, kVK_Undefined }, // 0xE7 + /* 232 */ { VC_UNDEFINED, kVK_Undefined }, // 0xE8 + /* 233 */ { VC_UNDEFINED, kVK_Undefined }, // 0xE9 + /* 234 */ { VC_UNDEFINED, kVK_Undefined }, // 0xEA + /* 235 */ { VC_UNDEFINED, kVK_Undefined }, // 0xEB + /* 236 */ { VC_UNDEFINED, kVK_Undefined }, // 0xEC + /* 237 */ { VC_UNDEFINED, kVK_Undefined }, // 0xED + /* 238 */ { VC_MEDIA_EJECT, kVK_Undefined }, // 0xEE + /* 239 */ { VC_UNDEFINED, kVK_Undefined }, // 0xEF + /* 240 */ { VC_MEDIA_PLAY, kVK_Undefined }, // 0xF0 + /* 241 */ { VC_MEDIA_NEXT, kVK_Undefined }, // 0xF1 + /* 242 */ { VC_MEDIA_PREVIOUS, kVK_Undefined }, // 0xF2 + /* 243 */ { VC_UNDEFINED, kVK_Undefined }, // 0xF3 + /* 244 */ { VC_UNDEFINED, kVK_Undefined }, // 0xF4 + /* 245 */ { VC_UNDEFINED, kVK_Undefined }, // 0xF5 + /* 246 */ { VC_UNDEFINED, kVK_Undefined }, // 0xF6 + /* 247 */ { VC_UNDEFINED, kVK_Undefined }, // 0xF7 + /* 248 */ { VC_UNDEFINED, kVK_Undefined }, // 0xF8 + /* 249 */ { VC_UNDEFINED, kVK_Undefined }, // 0xF9 + /* 250 */ { VC_UNDEFINED, kVK_Undefined }, // 0xFA + /* 251 */ { VC_UNDEFINED, kVK_Undefined }, // 0xFB + /* 252 */ { VC_UNDEFINED, kVK_Undefined }, // 0xFC + /* 253 */ { VC_UNDEFINED, kVK_Undefined }, // 0xFD + /* 254 */ { VC_UNDEFINED, kVK_Undefined }, // 0xFE + /* 255 */ { VC_UNDEFINED, kVK_Undefined }, // 0xFF +}; + +uint16_t keycode_to_scancode(UInt64 keycode) { + uint16_t scancode = VC_UNDEFINED; + + // Bound check 0 <= keycode < 256 + if (keycode < sizeof(keycode_scancode_table) / sizeof(keycode_scancode_table[0])) { + scancode = keycode_scancode_table[keycode][0]; + } + + return scancode; +} + +UInt64 scancode_to_keycode(uint16_t scancode) { + UInt64 keycode = kVK_Undefined; + + // Bound check 0 <= keycode < 128 + if (scancode < 128) { + keycode = keycode_scancode_table[scancode][1]; + } + else { + // Calculate the upper offset. + unsigned short i = (scancode & 0x007F) | 0x80; + + if (i < sizeof(keycode_scancode_table) / sizeof(keycode_scancode_table[1])) { + keycode = keycode_scancode_table[i][1]; + } + } + + return keycode; +} + +void load_input_helper() { + #if defined(USE_CARBON_LEGACY) || defined(USE_COREFOUNDATION) + // Start with a fresh dead key state. + //curr_deadkey_state = 0; + #endif +} + +void unload_input_helper() { + #if defined(USE_CARBON_LEGACY) || defined(USE_COREFOUNDATION) + if (prev_keyboard_layout != NULL) { + // Cleanup tracking of the previous layout. + CFRelease(prev_keyboard_layout); + prev_keyboard_layout = NULL; + } + #endif +} diff --git a/vendor/github.com/robotn/gohook/hook/darwin/properties_c.h b/vendor/github.com/robotn/gohook/hook/darwin/properties_c.h new file mode 100644 index 0000000..0a7679c --- /dev/null +++ b/vendor/github.com/robotn/gohook/hook/darwin/properties_c.h @@ -0,0 +1,522 @@ + +#ifdef HAVE_CONFIG_H + #include +#endif + +#ifdef USE_CARBON_LEGACY + #include +#endif +#ifdef USE_COREFOUNDATION + #include +#endif +#ifdef USE_IOKIT + #include + #include +#endif + +#include +#include "../iohook.h" +#include "input.h" +// #include "../logger_c.h" + +IOHOOK_API screen_data* hook_create_screen_info(unsigned char *count) { + CGError status = kCGErrorFailure; + screen_data* screens = NULL; + + // Initialize count to zero. + *count = 0; + + // Allocate memory to hold each display id. We will just allocate our MAX + // because its only about 1K of memory. + // TODO This can probably be realistically cut to something like 16 or 32.... + // If you have more than 32 monitors, send me a picture and make a donation ;) + CGDirectDisplayID *display_ids = malloc(sizeof(CGDirectDisplayID) * UCHAR_MAX); + if (display_ids != NULL) { + // NOTE Pass UCHAR_MAX to make sure uint32_t doesn't overflow uint8_t. + // TOOD Test/Check whether CGGetOnlineDisplayList is more suitable... + status = CGGetActiveDisplayList(UCHAR_MAX, display_ids, (uint32_t *) count); + + // If there is no error and at least one monitor. + if (status == kCGErrorSuccess && *count > 0) { + logger(LOG_LEVEL_INFO, "%s [%u]: CGGetActiveDisplayList: %li.\n", + __FUNCTION__, __LINE__, *count); + + // Allocate memory for the number of screens found. + screens = malloc(sizeof(screen_data) * (*count)); + if (screens != NULL) { + uint8_t i; + for (i = 0; i < *count; i++) { + //size_t width = CGDisplayPixelsWide(display_ids[i]); + //size_t height = CGDisplayPixelsHigh(display_ids[i]); + CGRect boundsDisp = CGDisplayBounds(display_ids[i]); + if (boundsDisp.size.width > 0 && boundsDisp.size.height > 0) { + screens[i] = (screen_data) { + .number = i + 1, + //TODO: make sure we follow the same convention for the origin + //in all other platform implementations (upper-left) + //TODO: document the approach with examples in order to show different + //cases -> different resolutions (secondary monitors origin might be + //negative) + .x = boundsDisp.origin.x, + .y = boundsDisp.origin.y, + .width = boundsDisp.size.width, + .height = boundsDisp.size.height + }; + } + } + } + } + else { + logger(LOG_LEVEL_INFO, "%s [%u]: multiple_get_screen_info failed: %ld. Fallback.\n", + __FUNCTION__, __LINE__, status); + + size_t width = CGDisplayPixelsWide(CGMainDisplayID()); + size_t height = CGDisplayPixelsHigh(CGMainDisplayID()); + + if (width > 0 && height > 0) { + screens = malloc(sizeof(screen_data)); + + if (screens != NULL) { + *count = 1; + screens[0] = (screen_data) { + .number = 1, + .x = 0, + .y = 0, + .width = width, + .height = height + }; + } + } + } + + // Free the id's after we are done. + free(display_ids); + } + + return screens; +} + +/* + * Apple's documentation is not very good. I was finally able to find this + * information after many hours of googling. Value is the slider value in the + * system preferences. That value * 15 is the rate in MS. 66 / the value is the + * chars per second rate. + * + * Value MS Char/Sec + * + * 1 15 66 * Out of standard range * + * + * 2 30 33 + * 6 90 11 + * 12 180 5.5 + * 30 450 2.2 + * 60 900 1.1 + * 90 1350 0.73 + * 120 1800 0.55 + * + * V = MS / 15 + * V = 66 / CharSec + * + * MS = V * 15 + * MS = (66 / CharSec) * 15 + * + * CharSec = 66 / V + * CharSec = 66 / (MS / 15) + */ + +IOHOOK_API long int hook_get_auto_repeat_rate() { + #if defined USE_IOKIT || defined USE_COREFOUNDATION || defined USE_CARBON_LEGACY + bool successful = false; + SInt64 rate; + #endif + + long int value = -1; + + #ifdef USE_IOKIT + if (!successful) { + io_service_t service = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching(kIOHIDSystemClass)); + if (service) { + kern_return_t kren_ret = kIOReturnError; + io_connect_t connection; + + kren_ret = IOServiceOpen(service, mach_task_self(), kIOHIDParamConnectType, &connection); + if (kren_ret == kIOReturnSuccess) { + IOByteCount size = sizeof(rate); + + kren_ret = IOHIDGetParameter(connection, CFSTR(kIOHIDKeyRepeatKey), (IOByteCount) sizeof(rate), &rate, &size); + if (kren_ret == kIOReturnSuccess) { + /* This is in some undefined unit of time that if we happen + * to multiply by 900 gives us the time in milliseconds. We + * add 0.5 to the result so that when we cast to long we + * actually get a rounded result. Saves the math.h depend. + * + * 33,333,333.0 / 1000.0 / 1000.0 / 1000.0 == 0.033333333 * Fast * + * 100,000,000.0 / 1000.0 / 1000.0 / 1000.0 == 0.1 + * 200,000,000.0 / 1000.0 / 1000.0 / 1000.0 == 0.2 + * 500,000,000.0 / 1000.0 / 1000.0 / 1000.0 == 0.5 + * 1,000,000,000.0 / 1000.0 / 1000.0 / 1000.0 == 1 + * 1,500,000,000.0 / 1000.0 / 1000.0 / 1000.0 == 1.5 + * 2,000,000,000.0 / 1000.0 / 1000.0 / 1000.0 == 2 * Slow * + */ + value = (long) (900.0 * ((double) rate) / 1000.0 / 1000.0 / 1000.0 + 0.5); + successful = true; + + logger(LOG_LEVEL_INFO, "%s [%u]: IOHIDGetParameter: %li.\n", + __FUNCTION__, __LINE__, value); + } + } + } + } + #endif + + #ifdef USE_COREFOUNDATION + if (!successful) { + CFTypeRef pref_val = CFPreferencesCopyValue(CFSTR("KeyRepeat"), kCFPreferencesAnyApplication, kCFPreferencesCurrentUser, kCFPreferencesAnyHost); + if (pref_val != NULL && CFGetTypeID(pref_val) == CFNumberGetTypeID()) { + if (CFNumberGetValue((CFNumberRef) pref_val, kCFNumberSInt32Type, &rate)) { + // This is the slider value, we must multiply by 15 to convert to milliseconds. + value = (long) rate * 15; + successful = true; + + logger(LOG_LEVEL_INFO, "%s [%u]: CFPreferencesCopyValue: %li.\n", + __FUNCTION__, __LINE__, value); + } + } + } + #endif + + #ifdef USE_CARBON_LEGACY + if (!successful) { + // Apple documentation states that value is in 'ticks'. I am not sure + // what that means, but it looks a lot like the arbitrary slider value. + rate = LMGetKeyRepThresh(); + if (rate > -1) { + /* This is the slider value, we must multiply by 15 to convert to + * milliseconds. + */ + value = (long) rate * 15; + successful = true; + + logger(LOG_LEVEL_INFO, "%s [%u]: LMGetKeyRepThresh: %li.\n", + __FUNCTION__, __LINE__, value); + } + } + #endif + + return value; +} + +IOHOOK_API long int hook_get_auto_repeat_delay() { + #if defined USE_IOKIT || defined USE_COREFOUNDATION || defined USE_CARBON_LEGACY + bool successful = false; + SInt64 delay; + #endif + + long int value = -1; + + #ifdef USE_IOKIT + if (!successful) { + io_service_t service = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching(kIOHIDSystemClass)); + if (service) { + kern_return_t kren_ret = kIOReturnError; + io_connect_t connection; + + kren_ret = IOServiceOpen(service, mach_task_self(), kIOHIDParamConnectType, &connection); + if (kren_ret == kIOReturnSuccess) { + IOByteCount size = sizeof(delay); + + kren_ret = IOHIDGetParameter(connection, CFSTR(kIOHIDInitialKeyRepeatKey), (IOByteCount) sizeof(delay), &delay, &size); + if (kren_ret == kIOReturnSuccess) { + /* This is in some undefined unit of time that if we happen + * to multiply by 900 gives us the time in milliseconds. We + * add 0.5 to the result so that when we cast to long we + * actually get a rounded result. Saves the math.h depend. + * + * 33,333,333.0 / 1000.0 / 1000.0 / 1000.0 == 0.033333333 * Fast * + * 100,000,000.0 / 1000.0 / 1000.0 / 1000.0 == 0.1 + * 200,000,000.0 / 1000.0 / 1000.0 / 1000.0 == 0.2 + * 500,000,000.0 / 1000.0 / 1000.0 / 1000.0 == 0.5 + * 1,000,000,000.0 / 1000.0 / 1000.0 / 1000.0 == 1 + * 1,500,000,000.0 / 1000.0 / 1000.0 / 1000.0 == 1.5 + * 2,000,000,000.0 / 1000.0 / 1000.0 / 1000.0 == 2 * Slow * + */ + value = (long) (900.0 * ((double) delay) / 1000.0 / 1000.0 / 1000.0 + 0.5); + successful = true; + + logger(LOG_LEVEL_INFO, "%s [%u]: IOHIDGetParameter: %li.\n", + __FUNCTION__, __LINE__, value); + } + } + } + } + #endif + + #ifdef USE_COREFOUNDATION + if (!successful) { + CFTypeRef pref_val = CFPreferencesCopyValue(CFSTR("InitialKeyRepeat"), kCFPreferencesAnyApplication, kCFPreferencesCurrentUser, kCFPreferencesAnyHost); + if (pref_val != NULL && CFGetTypeID(pref_val) == CFNumberGetTypeID()) { + if (CFNumberGetValue((CFNumberRef) pref_val, kCFNumberSInt32Type, &delay)) { + // This is the slider value, we must multiply by 15 to convert to + // milliseconds. + value = (long) delay * 15; + successful = true; + + logger(LOG_LEVEL_INFO, "%s [%u]: CFPreferencesCopyValue: %li.\n", + __FUNCTION__, __LINE__, value); + } + } + } + #endif + + #ifdef USE_CARBON_LEGACY + if (!successful) { + // Apple documentation states that value is in 'ticks'. I am not sure + // what that means, but it looks a lot like the arbitrary slider value. + delay = LMGetKeyThresh(); + if (delay > -1) { + // This is the slider value, we must multiply by 15 to convert to + // milliseconds. + value = (long) delay * 15; + successful = true; + + logger(LOG_LEVEL_INFO, "%s [%u]: LMGetKeyThresh: %li.\n", + __FUNCTION__, __LINE__, value); + } + } + #endif + + return value; +} + +IOHOOK_API long int hook_get_pointer_acceleration_multiplier() { + #if defined USE_IOKIT || defined USE_COREFOUNDATION + bool successful = false; + double multiplier; + #endif + + long int value = -1; + + #ifdef USE_IOKIT + if (!successful) { + io_service_t service = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching(kIOHIDSystemClass)); + + if (service) { + kern_return_t kren_ret = kIOReturnError; + io_connect_t connection; + + kren_ret = IOServiceOpen(service, mach_task_self(), kIOHIDParamConnectType, &connection); + if (kren_ret == kIOReturnSuccess) { + // IOByteCount size = sizeof(multiplier); + + kren_ret = IOHIDGetAccelerationWithKey(connection, CFSTR(kIOHIDMouseAccelerationType), &multiplier); + if (kren_ret == kIOReturnSuccess) { + // Calculate the greatest common factor. + + unsigned long denominator = 1000000, d = denominator; + unsigned long numerator = multiplier * denominator, gcf = numerator; + + while (d != 0) { + unsigned long i = gcf % d; + gcf = d; + d = i; + } + + value = denominator / gcf; + successful = true; + + logger(LOG_LEVEL_INFO, "%s [%u]: IOHIDGetAccelerationWithKey: %li.\n", + __FUNCTION__, __LINE__, value); + } + } + } + } + #endif + + #ifdef USE_COREFOUNDATION + if (!successful) { + CFTypeRef pref_val = CFPreferencesCopyValue(CFSTR("com.apple.mouse.scaling"), kCFPreferencesAnyApplication, kCFPreferencesCurrentUser, kCFPreferencesAnyHost); + if (pref_val != NULL && CFGetTypeID(pref_val) == CFNumberGetTypeID()) { + if (CFNumberGetValue((CFNumberRef) pref_val, kCFNumberSInt32Type, &multiplier)) { + value = (long) multiplier; + + logger(LOG_LEVEL_INFO, "%s [%u]: CFPreferencesCopyValue: %li.\n", + __FUNCTION__, __LINE__, value); + } + } + } + #endif + + return value; +} + +IOHOOK_API long int hook_get_pointer_acceleration_threshold() { + #if defined USE_COREFOUNDATION + bool successful = false; + SInt32 threshold; + #endif + + long int value = -1; + + #ifdef USE_COREFOUNDATION + if (!successful) { + CFTypeRef pref_val = CFPreferencesCopyValue(CFSTR("mouseDriverMaxSpeed"), CFSTR("com.apple.universalaccess"), kCFPreferencesCurrentUser, kCFPreferencesAnyHost); + if (pref_val != NULL && CFGetTypeID(pref_val) == CFNumberGetTypeID()) { + if (CFNumberGetValue((CFNumberRef) pref_val, kCFNumberSInt32Type, &threshold)) { + value = (long) threshold; + + logger(LOG_LEVEL_INFO, "%s [%u]: CFPreferencesCopyValue: %li.\n", + __FUNCTION__, __LINE__, value); + } + } + } + #endif + + return value; +} + +IOHOOK_API long int hook_get_pointer_sensitivity() { + #ifdef USE_IOKIT + bool successful = false; + double sensitivity; + #endif + + long int value = -1; + + #ifdef USE_IOKIT + if (!successful) { + io_service_t service = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching(kIOHIDSystemClass)); + + if (service) { + kern_return_t kren_ret = kIOReturnError; + io_connect_t connection; + + kren_ret = IOServiceOpen(service, mach_task_self(), kIOHIDParamConnectType, &connection); + if (kren_ret == kIOReturnSuccess) { + // IOByteCount size = sizeof(multiplier); + + kren_ret = IOHIDGetAccelerationWithKey(connection, CFSTR(kIOHIDMouseAccelerationType), &sensitivity); + if (kren_ret == kIOReturnSuccess) { + // Calculate the greatest common factor. + + unsigned long denominator = 1000000, d = denominator; + unsigned long numerator = sensitivity * denominator, gcf = numerator; + + while (d != 0) { + unsigned long i = gcf % d; + gcf = d; + d = i; + } + + value = numerator / gcf; + successful = true; + + logger(LOG_LEVEL_INFO, "%s [%u]: IOHIDGetAccelerationWithKey: %li.\n", + __FUNCTION__, __LINE__, value); + } + } + } + } + #endif + + return value; +} + +IOHOOK_API long int hook_get_multi_click_time() { + #if defined USE_IOKIT || defined USE_COREFOUNDATION || defined USE_CARBON_LEGACY + bool successful = false; + #if defined USE_IOKIT || defined USE_CARBON_LEGACY + // This needs to be defined only if we have USE_IOKIT or USE_CARBON_LEGACY. + SInt64 time; + #endif + #endif + + long int value = -1; + + #ifdef USE_IOKIT + if (!successful) { + io_service_t service = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching(kIOHIDSystemClass)); + if (service) { + kern_return_t kren_ret = kIOReturnError; + io_connect_t connection; + + kren_ret = IOServiceOpen(service, mach_task_self(), kIOHIDParamConnectType, &connection); + if (kren_ret == kIOReturnSuccess) { + IOByteCount size = sizeof(time); + + kren_ret = IOHIDGetParameter(connection, CFSTR(kIOHIDClickTimeKey), (IOByteCount) sizeof(time), &time, &size); + if (kren_ret == kIOReturnSuccess) { + /* This is in some undefined unit of time that if we happen + * to multiply by 900 gives us the time in milliseconds. We + * add 0.5 to the result so that when we cast to long we + * actually get a rounded result. Saves the math.h depend. + */ + value = (long) (900.0 * ((double) time) / 1000.0 / 1000.0 / 1000.0 + 0.5); + successful = true; + + logger(LOG_LEVEL_INFO, "%s [%u]: IOHIDGetParameter: %li.\n", + __FUNCTION__, __LINE__, value); + } + } + } + } + #endif + + #ifdef USE_COREFOUNDATION + if (!successful) { + Float32 clicktime; + CFTypeRef pref_val = CFPreferencesCopyValue(CFSTR("com.apple.mouse.doubleClickThreshold"), kCFPreferencesAnyApplication, kCFPreferencesCurrentUser, kCFPreferencesAnyHost); + if (pref_val != NULL && CFGetTypeID(pref_val) == CFNumberGetTypeID()) { + if (CFNumberGetValue((CFNumberRef) pref_val, kCFNumberFloat32Type, &clicktime)) { + /* This is in some undefined unit of time that if we happen + * to multiply by 900 gives us the time in milliseconds. It is + * completely possible that this value is in seconds and should be + * multiplied by 1000 but because IOKit values are undocumented and + * I have no idea what a Carbon 'tick' is so there really is no way + * to confirm this. + */ + value = (long) (clicktime * 900); + + logger(LOG_LEVEL_INFO, "%s [%u]: CFPreferencesCopyValue: %li.\n", + __FUNCTION__, __LINE__, value); + } + } + } + #endif + + #ifdef USE_CARBON_LEGACY + if (!successful) { + // Apple documentation states that value is in 'ticks'. I am not sure + // what that means, but it looks a lot like the arbitrary slider value. + time = GetDblTime(); + if (time > -1) { + // This is the slider value, we must multiply by 15 to convert to + // milliseconds. + value = (long) time * 15; + successful = true; + + logger(LOG_LEVEL_INFO, "%s [%u]: GetDblTime: %li.\n", + __FUNCTION__, __LINE__, value); + } + } + #endif + + return value; +} + + +// Create a shared object constructor. +__attribute__ ((constructor)) +void on_library_load() { + // Initialize Native Input Functions. + load_input_helper(); +} + +// Create a shared object destructor. +__attribute__ ((destructor)) +void on_library_unload() { + // Disable the event hook. + //hook_stop(); + + // Cleanup native input functions. + unload_input_helper(); +} diff --git a/vendor/github.com/robotn/gohook/hook/iohook.h b/vendor/github.com/robotn/gohook/hook/iohook.h new file mode 100644 index 0000000..db0ba8b --- /dev/null +++ b/vendor/github.com/robotn/gohook/hook/iohook.h @@ -0,0 +1,441 @@ + +#ifndef __IOHOOK_H +#define __IOHOOK_H + +// #include "../../base/os.h" +#include +#include +#include + +/* Begin Error Codes */ +#define IOHOOK_SUCCESS 0x00 +#define IOHOOK_FAILURE 0x01 + +// System level errors. +#define IOHOOK_ERROR_OUT_OF_MEMORY 0x02 + +// Unix specific errors. +#define IOHOOK_ERROR_X_OPEN_DISPLAY 0x20 +#define IOHOOK_ERROR_X_RECORD_NOT_FOUND 0x21 +#define IOHOOK_ERROR_X_RECORD_ALLOC_RANGE 0x22 +#define IOHOOK_ERROR_X_RECORD_CREATE_CONTEXT 0x23 +#define IOHOOK_ERROR_X_RECORD_ENABLE_CONTEXT 0x24 +#define IOHOOK_ERROR_X_RECORD_GET_CONTEXT 0x25 + +// Windows specific errors. +#define IOHOOK_ERROR_SET_WINDOWS_HOOK_EX 0x30 +#define IOHOOK_ERROR_GET_MODULE_HANDLE 0x31 + +// Darwin specific errors. +#define IOHOOK_ERROR_AXAPI_DISABLED 0x40 +#define IOHOOK_ERROR_CREATE_EVENT_PORT 0x41 +#define IOHOOK_ERROR_CREATE_RUN_LOOP_SOURCE 0x42 +#define IOHOOK_ERROR_GET_RUNLOOP 0x43 +#define IOHOOK_ERROR_CREATE_OBSERVER 0x44 +/* End Error Codes */ + +/* Begin Log Levels and Function Prototype */ +typedef enum _log_level { + LOG_LEVEL_DEBUG = 1, + LOG_LEVEL_INFO, + LOG_LEVEL_WARN, + LOG_LEVEL_ERROR +} log_level; + +// Logger callback function prototype. +typedef bool (*logger_t)(unsigned int, const char *, ...); +/* End Log Levels and Function Prototype */ + +/* Begin Virtual Event Types and Data Structures */ +typedef enum _event_type { + EVENT_HOOK_ENABLED = 1, + EVENT_HOOK_DISABLED, + EVENT_KEY_TYPED, + EVENT_KEY_PRESSED, + EVENT_KEY_RELEASED, + EVENT_MOUSE_CLICKED, + EVENT_MOUSE_PRESSED, + EVENT_MOUSE_RELEASED, + EVENT_MOUSE_MOVED, + EVENT_MOUSE_DRAGGED, + EVENT_MOUSE_WHEEL +} event_type; + +typedef struct _screen_data { + uint8_t number; + int16_t x; + int16_t y; + uint16_t width; + uint16_t height; +} screen_data; + +typedef struct _keyboard_event_data { + uint16_t keycode; + uint16_t rawcode; + uint16_t keychar; + // char *keychar; +} keyboard_event_data, + key_pressed_event_data, + key_released_event_data, + key_typed_event_data; + +typedef struct _mouse_event_data { + uint16_t button; + uint16_t clicks; + int16_t x; + int16_t y; +} mouse_event_data, + mouse_pressed_event_data, + mouse_released_event_data, + mouse_clicked_event_data; + +typedef struct _mouse_wheel_event_data { + uint16_t clicks; + int16_t x; + int16_t y; + uint8_t type; + uint16_t amount; + int16_t rotation; + uint8_t direction; +} mouse_wheel_event_data; + +typedef struct _iohook_event { + event_type type; + uint64_t time; + uint16_t mask; + uint16_t reserved; + union { + keyboard_event_data keyboard; + mouse_event_data mouse; + mouse_wheel_event_data wheel; + } data; +} iohook_event; + +typedef void (*dispatcher_t)(iohook_event *const); +/* End Virtual Event Types and Data Structures */ + + +/* Begin Virtual Key Codes */ +#define VC_ESCAPE 0x0001 + +// Begin Function Keys +#define VC_F1 0x003B +#define VC_F2 0x003C +#define VC_F3 0x003D +#define VC_F4 0x003E +#define VC_F5 0x003F +#define VC_F6 0x0040 +#define VC_F7 0x0041 +#define VC_F8 0x0042 +#define VC_F9 0x0043 +#define VC_F10 0x0044 +#define VC_F11 0x0057 +#define VC_F12 0x0058 + +#define VC_F13 0x005B +#define VC_F14 0x005C +#define VC_F15 0x005D +#define VC_F16 0x0063 +#define VC_F17 0x0064 +#define VC_F18 0x0065 +#define VC_F19 0x0066 +#define VC_F20 0x0067 +#define VC_F21 0x0068 +#define VC_F22 0x0069 +#define VC_F23 0x006A +#define VC_F24 0x006B +// End Function Keys + + +// Begin Alphanumeric Zone +#define VC_BACKQUOTE 0x0029 + +#define VC_1 0x0002 +#define VC_2 0x0003 +#define VC_3 0x0004 +#define VC_4 0x0005 +#define VC_5 0x0006 +#define VC_6 0x0007 +#define VC_7 0x0008 +#define VC_8 0x0009 +#define VC_9 0x000A +#define VC_0 0x000B + +#define VC_MINUS 0x000C // '-' +#define VC_EQUALS 0x000D // '=' +#define VC_BACKSPACE 0x000E + +#define VC_TAB 0x000F +#define VC_CAPS_LOCK 0x003A + +#define VC_A 0x001E +#define VC_B 0x0030 +#define VC_C 0x002E +#define VC_D 0x0020 +#define VC_E 0x0012 +#define VC_F 0x0021 +#define VC_G 0x0022 +#define VC_H 0x0023 +#define VC_I 0x0017 +#define VC_J 0x0024 +#define VC_K 0x0025 +#define VC_L 0x0026 +#define VC_M 0x0032 +#define VC_N 0x0031 +#define VC_O 0x0018 +#define VC_P 0x0019 +#define VC_Q 0x0010 +#define VC_R 0x0013 +#define VC_S 0x001F +#define VC_T 0x0014 +#define VC_U 0x0016 +#define VC_V 0x002F +#define VC_W 0x0011 +#define VC_X 0x002D +#define VC_Y 0x0015 +#define VC_Z 0x002C + +#define VC_OPEN_BRACKET 0x001A // '[' +#define VC_CLOSE_BRACKET 0x001B // ']' +#define VC_BACK_SLASH 0x002B // '\' + +#define VC_SEMICOLON 0x0027 // ';' +#define VC_QUOTE 0x0028 +#define VC_ENTER 0x001C + +#define VC_COMMA 0x0033 // ',' +#define VC_PERIOD 0x0034 // '.' +#define VC_SLASH 0x0035 // '/' + +#define VC_SPACE 0x0039 +// End Alphanumeric Zone + + +#define VC_PRINTSCREEN 0x0E37 +#define VC_SCROLL_LOCK 0x0046 +#define VC_PAUSE 0x0E45 + + +// Begin Edit Key Zone +#define VC_INSERT 0x0E52 +#define VC_DELETE 0x0E53 +#define VC_HOME 0x0E47 +#define VC_END 0x0E4F +#define VC_PAGE_UP 0x0E49 +#define VC_PAGE_DOWN 0x0E51 +// End Edit Key Zone + + +// Begin Cursor Key Zone +#define VC_UP 0xE048 +#define VC_LEFT 0xE04B +#define VC_CLEAR 0xE04C +#define VC_RIGHT 0xE04D +#define VC_DOWN 0xE050 +// End Cursor Key Zone + + +// Begin Numeric Zone +#define VC_NUM_LOCK 0x0045 +#define VC_KP_DIVIDE 0x0E35 +#define VC_KP_MULTIPLY 0x0037 +#define VC_KP_SUBTRACT 0x004A +#define VC_KP_EQUALS 0x0E0D +#define VC_KP_ADD 0x004E +#define VC_KP_ENTER 0x0E1C +#define VC_KP_SEPARATOR 0x0053 + +#define VC_KP_1 0x004F +#define VC_KP_2 0x0050 +#define VC_KP_3 0x0051 +#define VC_KP_4 0x004B +#define VC_KP_5 0x004C +#define VC_KP_6 0x004D +#define VC_KP_7 0x0047 +#define VC_KP_8 0x0048 +#define VC_KP_9 0x0049 +#define VC_KP_0 0x0052 + +#define VC_KP_END 0xEE00 | VC_KP_1 +#define VC_KP_DOWN 0xEE00 | VC_KP_2 +#define VC_KP_PAGE_DOWN 0xEE00 | VC_KP_3 +#define VC_KP_LEFT 0xEE00 | VC_KP_4 +#define VC_KP_CLEAR 0xEE00 | VC_KP_5 +#define VC_KP_RIGHT 0xEE00 | VC_KP_6 +#define VC_KP_HOME 0xEE00 | VC_KP_7 +#define VC_KP_UP 0xEE00 | VC_KP_8 +#define VC_KP_PAGE_UP 0xEE00 | VC_KP_9 +#define VC_KP_INSERT 0xEE00 | VC_KP_0 +#define VC_KP_DELETE 0xEE00 | VC_KP_SEPARATOR +// End Numeric Zone + + +// Begin Modifier and Control Keys +#define VC_SHIFT_L 0x002A +#define VC_SHIFT_R 0x0036 +#define VC_CONTROL_L 0x001D +#define VC_CONTROL_R 0x0E1D +#define VC_ALT_L 0x0038 // Option or Alt Key +#define VC_ALT_R 0x0E38 // Option or Alt Key +#define VC_META_L 0x0E5B // Windows or Command Key +#define VC_META_R 0x0E5C // Windows or Command Key +#define VC_CONTEXT_MENU 0x0E5D +// End Modifier and Control Keys + + +// Begin Media Control Keys +#define VC_POWER 0xE05E +#define VC_SLEEP 0xE05F +#define VC_WAKE 0xE063 + +#define VC_MEDIA_PLAY 0xE022 +#define VC_MEDIA_STOP 0xE024 +#define VC_MEDIA_PREVIOUS 0xE010 +#define VC_MEDIA_NEXT 0xE019 +#define VC_MEDIA_SELECT 0xE06D +#define VC_MEDIA_EJECT 0xE02C + +#define VC_VOLUME_MUTE 0xE020 +#define VC_VOLUME_UP 0xE030 +#define VC_VOLUME_DOWN 0xE02E + +#define VC_APP_MAIL 0xE06C +#define VC_APP_CALCULATOR 0xE021 +#define VC_APP_MUSIC 0xE03C +#define VC_APP_PICTURES 0xE064 + +#define VC_BROWSER_SEARCH 0xE065 +#define VC_BROWSER_HOME 0xE032 +#define VC_BROWSER_BACK 0xE06A +#define VC_BROWSER_FORWARD 0xE069 +#define VC_BROWSER_STOP 0xE068 +#define VC_BROWSER_REFRESH 0xE067 +#define VC_BROWSER_FAVORITES 0xE066 +// End Media Control Keys + +// Begin Japanese Language Keys +#define VC_KATAKANA 0x0070 +#define VC_UNDERSCORE 0x0073 +#define VC_FURIGANA 0x0077 +#define VC_KANJI 0x0079 +#define VC_HIRAGANA 0x007B +#define VC_YEN 0x007D +#define VC_KP_COMMA 0x007E +// End Japanese Language Keys + +// Begin Sun keyboards +#define VC_SUN_HELP 0xFF75 + +#define VC_SUN_STOP 0xFF78 +#define VC_SUN_PROPS 0xFF76 +#define VC_SUN_FRONT 0xFF77 +#define VC_SUN_OPEN 0xFF74 +#define VC_SUN_FIND 0xFF7E +#define VC_SUN_AGAIN 0xFF79 +#define VC_SUN_UNDO 0xFF7A +#define VC_SUN_COPY 0xFF7C +#define VC_SUN_INSERT 0xFF7D +#define VC_SUN_CUT 0xFF7B +// End Sun keyboards + +#define VC_UNDEFINED 0x0000 // KeyCode Unknown + +#define CHAR_UNDEFINED 0xFFFF // CharCode Unknown +/* End Virtual Key Codes */ + + +/* Begin Virtual Modifier Masks */ +#define MASK_SHIFT_L 1 << 0 +#define MASK_CTRL_L 1 << 1 +#define MASK_META_L 1 << 2 +#define MASK_ALT_L 1 << 3 + +#define MASK_SHIFT_R 1 << 4 +#define MASK_CTRL_R 1 << 5 +#define MASK_META_R 1 << 6 +#define MASK_ALT_R 1 << 7 + +#define MASK_SHIFT MASK_SHIFT_L | MASK_SHIFT_R +#define MASK_CTRL MASK_CTRL_L | MASK_CTRL_R +#define MASK_META MASK_META_L | MASK_META_R +#define MASK_ALT MASK_ALT_L | MASK_ALT_R + +#define MASK_BUTTON1 1 << 8 +#define MASK_BUTTON2 1 << 9 +#define MASK_BUTTON3 1 << 10 +#define MASK_BUTTON4 1 << 11 +#define MASK_BUTTON5 1 << 12 + +#define MASK_NUM_LOCK 1 << 13 +#define MASK_CAPS_LOCK 1 << 14 +#define MASK_SCROLL_LOCK 1 << 15 +/* End Virtual Modifier Masks */ + + +/* Begin Virtual Mouse Buttons */ +#define MOUSE_NOBUTTON 0 // Any Button +#define MOUSE_BUTTON1 1 // Left Button +#define MOUSE_BUTTON2 2 // Right Button +#define MOUSE_BUTTON3 3 // Middle Button +#define MOUSE_BUTTON4 4 // Extra Mouse Button +#define MOUSE_BUTTON5 5 // Extra Mouse Button + +#define WHEEL_UNIT_SCROLL 1 +#define WHEEL_BLOCK_SCROLL 2 + +#define WHEEL_VERTICAL_DIRECTION 3 +#define WHEEL_HORIZONTAL_DIRECTION 4 +/* End Virtual Mouse Buttons */ + + +#ifdef _WIN32 +#define IOHOOK_API __declspec(dllexport) +#else +#define IOHOOK_API +#endif + +#ifdef __cplusplus +extern "C" { +#endif + + // Set the logger callback functions. + IOHOOK_API void hook_set_logger_proc(logger_t logger_proc); + + // Send a virtual event back to the system. + IOHOOK_API void hook_post_event(iohook_event * const event); + + // Set the event callback function. + IOHOOK_API void hook_set_dispatch_proc(dispatcher_t dispatch_proc); + + // Insert the event hook. + IOHOOK_API int hook_run(); + + // Withdraw the event hook. + IOHOOK_API int hook_stop(); + + // Retrieves an array of screen data for each available monitor. + IOHOOK_API screen_data* hook_create_screen_info(unsigned char *count); + + // Retrieves the keyboard auto repeat rate. + IOHOOK_API long int hook_get_auto_repeat_rate(); + + // Retrieves the keyboard auto repeat delay. + IOHOOK_API long int hook_get_auto_repeat_delay(); + + // Retrieves the mouse acceleration multiplier. + IOHOOK_API long int hook_get_pointer_acceleration_multiplier(); + + // Retrieves the mouse acceleration threshold. + IOHOOK_API long int hook_get_pointer_acceleration_threshold(); + + // Retrieves the mouse sensitivity. + IOHOOK_API long int hook_get_pointer_sensitivity(); + + // Retrieves the double/triple click interval. + IOHOOK_API long int hook_get_multi_click_time(); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/vendor/github.com/robotn/gohook/hook/logger.h b/vendor/github.com/robotn/gohook/hook/logger.h new file mode 100644 index 0000000..0314e0f --- /dev/null +++ b/vendor/github.com/robotn/gohook/hook/logger.h @@ -0,0 +1,15 @@ + +#ifndef _included_logger +#define _included_logger + +#include "iohook.h" +#include + +#ifndef __FUNCTION__ +#define __FUNCTION__ __func__ +#endif + +// logger(level, message) +extern logger_t logger; + +#endif diff --git a/vendor/github.com/robotn/gohook/hook/logger_c.h b/vendor/github.com/robotn/gohook/hook/logger_c.h new file mode 100644 index 0000000..8752245 --- /dev/null +++ b/vendor/github.com/robotn/gohook/hook/logger_c.h @@ -0,0 +1,53 @@ + +#ifdef HAVE_CONFIG_H + #include +#endif + +#include +#include +#include +#include + +#include "iohook.h" +#include "logger.h" + +static bool default_logger(unsigned int level, const char *format, ...) { + bool status = false; + + #ifndef USE_QUIET + va_list args; + switch (level) { + #ifdef USE_DEBUG + case LOG_LEVEL_DEBUG: + #endif + case LOG_LEVEL_INFO: + va_start(args, format); + status = vfprintf(stdout, format, args) >= 0; + va_end(args); + break; + + case LOG_LEVEL_WARN: + case LOG_LEVEL_ERROR: + va_start(args, format); + status = vfprintf(stderr, format, args) >= 0; + va_end(args); + break; + } + #endif + + return status; +} + +// Current logger function pointer, this should never be null. +// FIXME This should be static and wrapped with a public facing function. +logger_t logger = &default_logger; + + +IOHOOK_API void hookSetlogger(logger_t logger_proc) { + if (logger_proc == NULL) { + logger = &default_logger; + } + else { + logger = logger_proc; + } +} diff --git a/vendor/github.com/robotn/gohook/hook/windows/event_c.h b/vendor/github.com/robotn/gohook/hook/windows/event_c.h new file mode 100644 index 0000000..2eb51f6 --- /dev/null +++ b/vendor/github.com/robotn/gohook/hook/windows/event_c.h @@ -0,0 +1,328 @@ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include "../iohook.h" +#include + +// #include "logger.h" +#include "input.h" + +// Some buggy versions of MinGW and MSys do not include these constants in winuser.h. +#ifndef MAPVK_VK_TO_VSC +#define MAPVK_VK_TO_VSC 0 +#define MAPVK_VSC_TO_VK 1 +#define MAPVK_VK_TO_CHAR 2 +#define MAPVK_VSC_TO_VK_EX 3 +#endif +// Some buggy versions of MinGW and MSys only define this value for Windows +// versions >= 0x0600 (Windows Vista) when it should be 0x0500 (Windows 2000). +#ifndef MAPVK_VK_TO_VSC_EX +#define MAPVK_VK_TO_VSC_EX 4 +#endif + +#ifndef KEYEVENTF_SCANCODE +#define KEYEVENTF_EXTENDEDKEY 0x0001 +#define KEYEVENTF_KEYUP 0x0002 +#define KEYEVENTF_UNICODE 0x0004 +#define KEYEVENTF_SCANCODE 0x0008 +#endif + +#ifndef KEYEVENTF_KEYDOWN +#define KEYEVENTF_KEYDOWN 0x0000 +#endif + +#define MAX_WINDOWS_COORD_VALUE 65535 + +static UINT keymask_lookup[8] = { + VK_LSHIFT, + VK_LCONTROL, + VK_LWIN, + VK_LMENU, + + VK_RSHIFT, + VK_RCONTROL, + VK_RWIN, + VK_RMENU +}; + +IOHOOK_API void hook_post_event(iohook_event * const event) { + //FIXME implement multiple monitor support + uint16_t screen_width = GetSystemMetrics( SM_CXSCREEN ); + uint16_t screen_height = GetSystemMetrics( SM_CYSCREEN ); + + unsigned char events_size = 0, events_max = 28; + INPUT *events = malloc(sizeof(INPUT) * events_max); + + if (event->mask & (MASK_SHIFT | MASK_CTRL | MASK_META | MASK_ALT)) { + unsigned int i; + for (i = 0; i < sizeof(keymask_lookup) / sizeof(UINT); i++) { + if (event->mask & 1 << i) { + events[events_size].type = INPUT_KEYBOARD; + events[events_size].ki.wVk = keymask_lookup[i]; + events[events_size].ki.dwFlags = KEYEVENTF_KEYDOWN; + events[events_size].ki.time = 0; // Use current system time. + events_size++; + } + } + } + + if (event->mask & (MASK_BUTTON1 | MASK_BUTTON2 | MASK_BUTTON3 | MASK_BUTTON4 | MASK_BUTTON5)) { + events[events_size].type = INPUT_MOUSE; + events[events_size].mi.dx = 0; // Relative mouse movement due to + events[events_size].mi.dy = 0; // MOUSEEVENTF_ABSOLUTE not being set. + events[events_size].mi.mouseData = 0x00; + events[events_size].mi.time = 0; // Use current system time. + + if (event->mask & MASK_BUTTON1) { + events[events_size].mi.mouseData |= MOUSEEVENTF_LEFTDOWN; + } + + if (event->mask & MASK_BUTTON2) { + events[events_size].mi.mouseData |= MOUSEEVENTF_RIGHTDOWN; + } + + if (event->mask & MASK_BUTTON3) { + events[events_size].mi.mouseData |= MOUSEEVENTF_MIDDLEDOWN; + } + + if (event->mask & MASK_BUTTON4) { + events[events_size].mi.mouseData = XBUTTON1; + events[events_size].mi.mouseData |= MOUSEEVENTF_XDOWN; + } + + if (event->mask & MASK_BUTTON5) { + events[events_size].mi.mouseData = XBUTTON2; + events[events_size].mi.dwFlags |= MOUSEEVENTF_XDOWN; + } + + events_size++; + } + + + switch (event->type) { + case EVENT_KEY_PRESSED: + events[events_size].ki.wVk = scancode_to_keycode(event->data.keyboard.keycode); + if (events[events_size].ki.wVk != 0x0000) { + events[events_size].type = INPUT_KEYBOARD; + events[events_size].ki.dwFlags = KEYEVENTF_KEYDOWN; // |= KEYEVENTF_SCANCODE; + events[events_size].ki.wScan = 0; // event->data.keyboard.keycode; + events[events_size].ki.time = 0; // GetSystemTime() + events_size++; + } + else { + logger(LOG_LEVEL_INFO, "%s [%u]: Unable to lookup scancode: %li\n", + __FUNCTION__, __LINE__, + event->data.keyboard.keycode); + } + break; + + case EVENT_KEY_RELEASED: + events[events_size].ki.wVk = scancode_to_keycode(event->data.keyboard.keycode); + if (events[events_size].ki.wVk != 0x0000) { + events[events_size].type = INPUT_KEYBOARD; + events[events_size].ki.dwFlags = KEYEVENTF_KEYUP; // |= KEYEVENTF_SCANCODE; + events[events_size].ki.wVk = scancode_to_keycode(event->data.keyboard.keycode); + events[events_size].ki.wScan = 0; // event->data.keyboard.keycode; + events[events_size].ki.time = 0; // GetSystemTime() + events_size++; + } + else { + logger(LOG_LEVEL_INFO, "%s [%u]: Unable to lookup scancode: %li\n", + __FUNCTION__, __LINE__, + event->data.keyboard.keycode); + } + break; + + + case EVENT_MOUSE_PRESSED: + events[events_size].type = INPUT_MOUSE; + events[events_size].mi.dwFlags = MOUSEEVENTF_XDOWN; + + switch (event->data.mouse.button) { + case MOUSE_BUTTON1: + events[events_size].mi.dwFlags = MOUSEEVENTF_LEFTDOWN; + break; + + case MOUSE_BUTTON2: + events[events_size].mi.dwFlags = MOUSEEVENTF_RIGHTDOWN; + break; + + case MOUSE_BUTTON3: + events[events_size].mi.dwFlags = MOUSEEVENTF_MIDDLEDOWN; + break; + + case MOUSE_BUTTON4: + events[events_size].mi.mouseData = XBUTTON1; + break; + + case MOUSE_BUTTON5: + events[events_size].mi.mouseData = XBUTTON2; + break; + + default: + // Extra buttons. + if (event->data.mouse.button > 3) { + events[events_size].mi.mouseData = event->data.mouse.button - 3; + } + } + + events[events_size].mi.dx = event->data.mouse.x * (MAX_WINDOWS_COORD_VALUE / screen_width) + 1; + events[events_size].mi.dy = event->data.mouse.y * (MAX_WINDOWS_COORD_VALUE / screen_height) + 1; + + events[events_size].mi.dwFlags |= MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE; + events[events_size].mi.time = 0; // GetSystemTime() + + events_size++; + break; + + case EVENT_MOUSE_RELEASED: + events[events_size].type = INPUT_MOUSE; + events[events_size].mi.dwFlags = MOUSEEVENTF_XUP; + + switch (event->data.mouse.button) { + case MOUSE_BUTTON1: + events[events_size].mi.dwFlags = MOUSEEVENTF_LEFTUP; + break; + + case MOUSE_BUTTON2: + events[events_size].mi.dwFlags = MOUSEEVENTF_RIGHTUP; + break; + + case MOUSE_BUTTON3: + events[events_size].mi.dwFlags = MOUSEEVENTF_MIDDLEUP; + break; + + case MOUSE_BUTTON4: + events[events_size].mi.mouseData = XBUTTON1; + break; + + case MOUSE_BUTTON5: + events[events_size].mi.mouseData = XBUTTON2; + break; + + default: + // Extra buttons. + if (event->data.mouse.button > 3) { + events[events_size].mi.mouseData = event->data.mouse.button - 3; + } + } + + events[events_size].mi.dx = event->data.mouse.x * (MAX_WINDOWS_COORD_VALUE / screen_width) + 1; + events[events_size].mi.dy = event->data.mouse.y * (MAX_WINDOWS_COORD_VALUE / screen_height) + 1; + + events[events_size].mi.dwFlags |= MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE; + events[events_size].mi.time = 0; // GetSystemTime() + events_size++; + break; + + + case EVENT_MOUSE_WHEEL: + events[events_size].type = INPUT_MOUSE; + events[events_size].mi.dwFlags = MOUSEEVENTF_WHEEL; + + // type, amount and rotation? + events[events_size].mi.mouseData = event->data.wheel.amount * event->data.wheel.rotation * WHEEL_DELTA; + + events[events_size].mi.dx = event->data.wheel.x * (MAX_WINDOWS_COORD_VALUE / screen_width) + 1; + events[events_size].mi.dy = event->data.wheel.y * (MAX_WINDOWS_COORD_VALUE / screen_height) + 1; + + events[events_size].mi.dwFlags |= MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE; + events[events_size].mi.time = 0; // GetSystemTime() + events_size++; + break; + + + case EVENT_MOUSE_DRAGGED: + // The button masks are all applied with the modifier masks. + + case EVENT_MOUSE_MOVED: + events[events_size].type = INPUT_MOUSE; + events[events_size].mi.dwFlags = MOUSEEVENTF_MOVE; + + events[events_size].mi.dx = event->data.mouse.x * (MAX_WINDOWS_COORD_VALUE / screen_width) + 1; + events[events_size].mi.dy = event->data.mouse.y * (MAX_WINDOWS_COORD_VALUE / screen_height) + 1; + + events[events_size].mi.dwFlags |= MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE; + events[events_size].mi.time = 0; // GetSystemTime() + events_size++; + break; + + + case EVENT_MOUSE_CLICKED: + case EVENT_KEY_TYPED: + // Ignore clicked and typed events. + + case EVENT_HOOK_ENABLED: + case EVENT_HOOK_DISABLED: + // Ignore hook enabled / disabled events. + + default: + // Ignore any other garbage. + logger(LOG_LEVEL_WARN, "%s [%u]: Ignoring post event type %#X\n", + __FUNCTION__, __LINE__, event->type); + break; + } + + // Release the previously held modifier keys used to fake the event mask. + if (event->mask & (MASK_SHIFT | MASK_CTRL | MASK_META | MASK_ALT)) { + unsigned int i; + for (i = 0; i < sizeof(keymask_lookup) / sizeof(UINT); i++) { + if (event->mask & 1 << i) { + events[events_size].type = INPUT_KEYBOARD; + events[events_size].ki.wVk = keymask_lookup[i]; + events[events_size].ki.dwFlags = KEYEVENTF_KEYUP; + events[events_size].ki.time = 0; // Use current system time. + events_size++; + } + } + } + + if (event->mask & (MASK_BUTTON1 | MASK_BUTTON2 | MASK_BUTTON3 | MASK_BUTTON4 | MASK_BUTTON5)) { + events[events_size].type = INPUT_MOUSE; + events[events_size].mi.dx = 0; // Relative mouse movement due to + events[events_size].mi.dy = 0; // MOUSEEVENTF_ABSOLUTE not being set. + events[events_size].mi.mouseData = 0x00; + events[events_size].mi.time = 0; // Use current system time. + + // If dwFlags does not contain MOUSEEVENTF_WHEEL, MOUSEEVENTF_XDOWN, or MOUSEEVENTF_XUP, + // then mouseData should be zero. + // http://msdn.microsoft.com/en-us/library/windows/desktop/ms646273%28v=vs.85%29.aspx + if (event->mask & MASK_BUTTON1) { + events[events_size].mi.dwFlags |= MOUSEEVENTF_LEFTUP; + } + + if (event->mask & MASK_BUTTON2) { + events[events_size].mi.dwFlags |= MOUSEEVENTF_RIGHTUP; + } + + if (event->mask & MASK_BUTTON3) { + events[events_size].mi.dwFlags |= MOUSEEVENTF_MIDDLEUP; + } + + if (event->mask & MASK_BUTTON4) { + events[events_size].mi.mouseData = XBUTTON1; + events[events_size].mi.dwFlags |= MOUSEEVENTF_XUP; + } + + if (event->mask & MASK_BUTTON5) { + events[events_size].mi.mouseData = XBUTTON2; + events[events_size].mi.dwFlags |= MOUSEEVENTF_XUP; + } + + events_size++; + } + + // Create the key release input + // memcpy(key_events + 1, key_events, sizeof(INPUT)); + // key_events[1].ki.dwFlags |= KEYEVENTF_KEYUP; + + if (! SendInput(events_size, events, sizeof(INPUT)) ) { + logger(LOG_LEVEL_ERROR, "%s [%u]: SendInput() failed! (%#lX)\n", + __FUNCTION__, __LINE__, (unsigned long) GetLastError()); + } + + free(events); +} diff --git a/vendor/github.com/robotn/gohook/hook/windows/hook_c.h b/vendor/github.com/robotn/gohook/hook/windows/hook_c.h new file mode 100644 index 0000000..ed15515 --- /dev/null +++ b/vendor/github.com/robotn/gohook/hook/windows/hook_c.h @@ -0,0 +1,747 @@ + +#ifdef HAVE_CONFIG_H + #include +#endif + +#include +#include + +#include "../iohook.h" +#include "input.h" +// #include "logger.h" + +// Thread and hook handles. +static DWORD hook_thread_id = 0; +static HHOOK keyboard_event_hhook = NULL, mouse_event_hhook = NULL; +static HWINEVENTHOOK win_event_hhook = NULL; + +// The handle to the DLL module pulled in DllMain on DLL_PROCESS_ATTACH. +extern HINSTANCE hInst; + +// Modifiers for tracking key masks. +static unsigned short int current_modifiers = 0x0000; + +// Click count globals. +static unsigned short click_count = 0; +static DWORD click_time = 0; +static unsigned short int click_button = MOUSE_NOBUTTON; +static POINT last_click; + +// Static event memory. +static iohook_event event; + +// Event dispatch callback. +static dispatcher_t dispatcher = NULL; + +IOHOOK_API void hook_set_dispatch_proc(dispatcher_t dispatch_proc) { + logger(LOG_LEVEL_DEBUG, "%s [%u]: Setting new dispatch callback to %#p.\n", + __FUNCTION__, __LINE__, dispatch_proc); + + dispatcher = dispatch_proc; +} + +// Send out an event if a dispatcher was set. +static inline void dispatch_event(iohook_event *const event) { + if (dispatcher != NULL) { + logger(LOG_LEVEL_DEBUG, "%s [%u]: Dispatching event type %u.\n", + __FUNCTION__, __LINE__, event->type); + + dispatcher(event); + } + else { + logger(LOG_LEVEL_WARN, "%s [%u]: No dispatch callback set!\n", + __FUNCTION__, __LINE__); + } +} + + +// Set the native modifier mask for future events. +static inline void set_modifier_mask(unsigned short int mask) { + current_modifiers |= mask; +} + +// Unset the native modifier mask for future events. +static inline void unset_modifier_mask(unsigned short int mask) { + current_modifiers ^= mask; +} + +// Get the current native modifier mask state. +static inline unsigned short int get_modifiers() { + return current_modifiers; +} + +// Initialize the modifier mask to the current modifiers. +static void initialize_modifiers() { + current_modifiers = 0x0000; + + // NOTE We are checking the high order bit, so it will be < 0 for a singed short. + if (GetKeyState(VK_LSHIFT) < 0) { set_modifier_mask(MASK_SHIFT_L); } + if (GetKeyState(VK_RSHIFT) < 0) { set_modifier_mask(MASK_SHIFT_R); } + if (GetKeyState(VK_LCONTROL) < 0) { set_modifier_mask(MASK_CTRL_L); } + if (GetKeyState(VK_RCONTROL) < 0) { set_modifier_mask(MASK_CTRL_R); } + if (GetKeyState(VK_LMENU) < 0) { set_modifier_mask(MASK_ALT_L); } + if (GetKeyState(VK_RMENU) < 0) { set_modifier_mask(MASK_ALT_R); } + if (GetKeyState(VK_LWIN) < 0) { set_modifier_mask(MASK_META_L); } + if (GetKeyState(VK_RWIN) < 0) { set_modifier_mask(MASK_META_R); } + + if (GetKeyState(VK_LBUTTON) < 0) { set_modifier_mask(MASK_BUTTON1); } + if (GetKeyState(VK_RBUTTON) < 0) { set_modifier_mask(MASK_BUTTON2); } + if (GetKeyState(VK_MBUTTON) < 0) { set_modifier_mask(MASK_BUTTON3); } + if (GetKeyState(VK_XBUTTON1) < 0) { set_modifier_mask(MASK_BUTTON4); } + if (GetKeyState(VK_XBUTTON2) < 0) { set_modifier_mask(MASK_BUTTON5); } + + if (GetKeyState(VK_NUMLOCK) < 0) { set_modifier_mask(MASK_NUM_LOCK); } + if (GetKeyState(VK_CAPITAL) < 0) { set_modifier_mask(MASK_CAPS_LOCK); } + if (GetKeyState(VK_SCROLL) < 0) { set_modifier_mask(MASK_SCROLL_LOCK); } +} + + +/* Retrieves the mouse wheel scroll type. This function cannot be included as + * part of the input.h due to platform specific calling restrictions. + */ +static unsigned short int get_scroll_wheel_type() { + unsigned short int value; + UINT wheel_type; + + SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 0, &wheel_type, 0); + if (wheel_type == WHEEL_PAGESCROLL) { + value = WHEEL_BLOCK_SCROLL; + } + else { + value = WHEEL_UNIT_SCROLL; + } + + return value; +} + +/* Retrieves the mouse wheel scroll amount. This function cannot be included as + * part of the input.h due to platform specific calling restrictions. + */ +static unsigned short int get_scroll_wheel_amount() { + unsigned short int value; + UINT wheel_amount; + + SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 0, &wheel_amount, 0); + if (wheel_amount == WHEEL_PAGESCROLL) { + value = 1; + } + else { + value = (unsigned short int) wheel_amount; + } + + return value; +} + +void unregister_running_hooks() { + // Stop the event hook and any timer still running. + if (win_event_hhook != NULL) { + UnhookWinEvent(win_event_hhook); + win_event_hhook = NULL; + } + + // Destroy the native hooks. + if (keyboard_event_hhook != NULL) { + UnhookWindowsHookEx(keyboard_event_hhook); + keyboard_event_hhook = NULL; + } + + if (mouse_event_hhook != NULL) { + UnhookWindowsHookEx(mouse_event_hhook); + mouse_event_hhook = NULL; + } +} + +void hook_start_proc() { + // Get the local system time in UNIX epoch form. + uint64_t timestamp = GetMessageTime(); + + // Populate the hook start event. + event.time = timestamp; + event.reserved = 0x00; + + event.type = EVENT_HOOK_ENABLED; + event.mask = 0x00; + + // Fire the hook start event. + dispatch_event(&event); +} + +void hook_stop_proc() { + // Get the local system time in UNIX epoch form. + uint64_t timestamp = GetMessageTime(); + + // Populate the hook stop event. + event.time = timestamp; + event.reserved = 0x00; + + event.type = EVENT_HOOK_DISABLED; + event.mask = 0x00; + + // Fire the hook stop event. + dispatch_event(&event); +} + +static void process_key_pressed(KBDLLHOOKSTRUCT *kbhook) { + // Check and setup modifiers. + if (kbhook->vkCode == VK_LSHIFT) { set_modifier_mask(MASK_SHIFT_L); } + else if (kbhook->vkCode == VK_RSHIFT) { set_modifier_mask(MASK_SHIFT_R); } + else if (kbhook->vkCode == VK_LCONTROL) { set_modifier_mask(MASK_CTRL_L); } + else if (kbhook->vkCode == VK_RCONTROL) { set_modifier_mask(MASK_CTRL_R); } + else if (kbhook->vkCode == VK_LMENU) { set_modifier_mask(MASK_ALT_L); } + else if (kbhook->vkCode == VK_RMENU) { set_modifier_mask(MASK_ALT_R); } + else if (kbhook->vkCode == VK_LWIN) { set_modifier_mask(MASK_META_L); } + else if (kbhook->vkCode == VK_RWIN) { set_modifier_mask(MASK_META_R); } + else if (kbhook->vkCode == VK_NUMLOCK) { set_modifier_mask(MASK_NUM_LOCK); } + else if (kbhook->vkCode == VK_CAPITAL) { set_modifier_mask(MASK_CAPS_LOCK); } + else if (kbhook->vkCode == VK_SCROLL) { set_modifier_mask(MASK_SCROLL_LOCK); } + + // Populate key pressed event. + event.time = kbhook->time; + event.reserved = 0x00; + + event.type = EVENT_KEY_PRESSED; + event.mask = get_modifiers(); + + event.data.keyboard.keycode = keycode_to_scancode(kbhook->vkCode, kbhook->flags); + event.data.keyboard.rawcode = kbhook->vkCode; + event.data.keyboard.keychar = CHAR_UNDEFINED; + + logger(LOG_LEVEL_INFO, "%s [%u]: Key %#X pressed. (%#X)\n", + __FUNCTION__, __LINE__, event.data.keyboard.keycode, event.data.keyboard.rawcode); + + // Populate key pressed event. + dispatch_event(&event); + + // If the pressed event was not consumed... + if (event.reserved ^ 0x01) { + // Buffer for unicode typed chars. No more than 2 needed. + WCHAR buffer[2]; // = { WCH_NONE }; + + // If the pressed event was not consumed and a unicode char exists... + SIZE_T count = keycode_to_unicode(kbhook->vkCode, buffer, sizeof(buffer)); + unsigned int i; + for (i = 0; i < count; i++) { + // Populate key typed event. + event.time = kbhook->time; + event.reserved = 0x00; + + event.type = EVENT_KEY_TYPED; + event.mask = get_modifiers(); + + event.data.keyboard.keycode = VC_UNDEFINED; + event.data.keyboard.rawcode = kbhook->vkCode; + event.data.keyboard.keychar = buffer[i]; + + logger(LOG_LEVEL_INFO, "%s [%u]: Key %#X typed. (%lc)\n", + __FUNCTION__, __LINE__, event.data.keyboard.keycode, (wint_t) event.data.keyboard.keychar); + + // Fire key typed event. + dispatch_event(&event); + } + } +} + +static void process_key_released(KBDLLHOOKSTRUCT *kbhook) { + // Check and setup modifiers. + if (kbhook->vkCode == VK_LSHIFT) { unset_modifier_mask(MASK_SHIFT_L); } + else if (kbhook->vkCode == VK_RSHIFT) { unset_modifier_mask(MASK_SHIFT_R); } + else if (kbhook->vkCode == VK_LCONTROL) { unset_modifier_mask(MASK_CTRL_L); } + else if (kbhook->vkCode == VK_RCONTROL) { unset_modifier_mask(MASK_CTRL_R); } + else if (kbhook->vkCode == VK_LMENU) { unset_modifier_mask(MASK_ALT_L); } + else if (kbhook->vkCode == VK_RMENU) { unset_modifier_mask(MASK_ALT_R); } + else if (kbhook->vkCode == VK_LWIN) { unset_modifier_mask(MASK_META_L); } + else if (kbhook->vkCode == VK_RWIN) { unset_modifier_mask(MASK_META_R); } + else if (kbhook->vkCode == VK_NUMLOCK) { unset_modifier_mask(MASK_NUM_LOCK); } + else if (kbhook->vkCode == VK_CAPITAL) { unset_modifier_mask(MASK_CAPS_LOCK); } + else if (kbhook->vkCode == VK_SCROLL) { unset_modifier_mask(MASK_SCROLL_LOCK); } + + // Populate key pressed event. + event.time = kbhook->time; + event.reserved = 0x00; + + event.type = EVENT_KEY_RELEASED; + event.mask = get_modifiers(); + + event.data.keyboard.keycode = keycode_to_scancode(kbhook->vkCode, kbhook->flags); + event.data.keyboard.rawcode = kbhook->vkCode; + event.data.keyboard.keychar = CHAR_UNDEFINED; + + logger(LOG_LEVEL_INFO, "%s [%u]: Key %#X released. (%#X)\n", + __FUNCTION__, __LINE__, event.data.keyboard.keycode, event.data.keyboard.rawcode); + + // Fire key released event. + dispatch_event(&event); +} + +LRESULT CALLBACK keyboard_hook_event_proc(int nCode, WPARAM wParam, LPARAM lParam) { + KBDLLHOOKSTRUCT *kbhook = (KBDLLHOOKSTRUCT *) lParam; + switch (wParam) { + case WM_KEYDOWN: + case WM_SYSKEYDOWN: + process_key_pressed(kbhook); + break; + + case WM_KEYUP: + case WM_SYSKEYUP: + process_key_released(kbhook); + break; + + default: + // In theory this *should* never execute. + logger(LOG_LEVEL_DEBUG, "%s [%u]: Unhandled Windows keyboard event: %#X.\n", + __FUNCTION__, __LINE__, (unsigned int) wParam); + break; + } + + LRESULT hook_result = -1; + if (nCode < 0 || event.reserved ^ 0x01) { + hook_result = CallNextHookEx(keyboard_event_hhook, nCode, wParam, lParam); + } + else { + logger(LOG_LEVEL_DEBUG, "%s [%u]: Consuming the current event. (%li)\n", + __FUNCTION__, __LINE__, (long) hook_result); + } + + return hook_result; +} + + +static void process_button_pressed(MSLLHOOKSTRUCT *mshook, uint16_t button) { + uint64_t timestamp = GetMessageTime(); + + // Track the number of clicks, the button must match the previous button. + if (button == click_button && (long int) (timestamp - click_time) <= hook_get_multi_click_time()) { + if (click_count < USHRT_MAX) { + click_count++; + } + else { + logger(LOG_LEVEL_WARN, "%s [%u]: Click count overflow detected!\n", + __FUNCTION__, __LINE__); + } + } + else { + // Reset the click count. + click_count = 1; + + // Set the previous button. + click_button = button; + } + + // Save this events time to calculate the click_count. + click_time = timestamp; + + // Store the last click point. + last_click.x = mshook->pt.x; + last_click.y = mshook->pt.y; + + // Populate mouse pressed event. + event.time = timestamp; + event.reserved = 0x00; + + event.type = EVENT_MOUSE_PRESSED; + event.mask = get_modifiers(); + + event.data.mouse.button = button; + event.data.mouse.clicks = click_count; + + event.data.mouse.x = mshook->pt.x; + event.data.mouse.y = mshook->pt.y; + + logger(LOG_LEVEL_INFO, "%s [%u]: Button %u pressed %u time(s). (%u, %u)\n", + __FUNCTION__, __LINE__, event.data.mouse.button, event.data.mouse.clicks, + event.data.mouse.x, event.data.mouse.y); + + // Fire mouse pressed event. + dispatch_event(&event); +} + +static void process_button_released(MSLLHOOKSTRUCT *mshook, uint16_t button) { + // Populate mouse released event. + event.time = GetMessageTime(); + event.reserved = 0x00; + + event.type = EVENT_MOUSE_RELEASED; + event.mask = get_modifiers(); + + event.data.mouse.button = button; + event.data.mouse.clicks = click_count; + + event.data.mouse.x = mshook->pt.x; + event.data.mouse.y = mshook->pt.y; + + logger(LOG_LEVEL_INFO, "%s [%u]: Button %u released %u time(s). (%u, %u)\n", + __FUNCTION__, __LINE__, event.data.mouse.button, + event.data.mouse.clicks, + event.data.mouse.x, event.data.mouse.y); + + // Fire mouse released event. + dispatch_event(&event); + + // If the pressed event was not consumed... + if (event.reserved ^ 0x01 && last_click.x == mshook->pt.x && last_click.y == mshook->pt.y) { + // Populate mouse clicked event. + event.time = GetMessageTime(); + event.reserved = 0x00; + + event.type = EVENT_MOUSE_CLICKED; + event.mask = get_modifiers(); + + event.data.mouse.button = button; + event.data.mouse.clicks = click_count; + event.data.mouse.x = mshook->pt.x; + event.data.mouse.y = mshook->pt.y; + + logger(LOG_LEVEL_INFO, "%s [%u]: Button %u clicked %u time(s). (%u, %u)\n", + __FUNCTION__, __LINE__, event.data.mouse.button, event.data.mouse.clicks, + event.data.mouse.x, event.data.mouse.y); + + // Fire mouse clicked event. + dispatch_event(&event); + } + + // Reset the number of clicks. + if (button == click_button && (long int) (event.time - click_time) > hook_get_multi_click_time()) { + // Reset the click count. + click_count = 0; + } +} + +static void process_mouse_moved(MSLLHOOKSTRUCT *mshook) { + uint64_t timestamp = GetMessageTime(); + + // We received a mouse move event with the mouse actually moving. + // This verifies that the mouse was moved after being depressed. + if (last_click.x != mshook->pt.x || last_click.y != mshook->pt.y) { + // Reset the click count. + if (click_count != 0 && (long) (timestamp - click_time) > hook_get_multi_click_time()) { + click_count = 0; + } + + // Populate mouse move event. + event.time = timestamp; + event.reserved = 0x00; + + event.mask = get_modifiers(); + + // Check the modifier mask range for MASK_BUTTON1 - 5. + bool mouse_dragged = event.mask & (MASK_BUTTON1 | MASK_BUTTON2 | MASK_BUTTON3 | MASK_BUTTON4 | MASK_BUTTON5); + if (mouse_dragged) { + // Create Mouse Dragged event. + event.type = EVENT_MOUSE_DRAGGED; + } + else { + // Create a Mouse Moved event. + event.type = EVENT_MOUSE_MOVED; + } + + event.data.mouse.button = MOUSE_NOBUTTON; + event.data.mouse.clicks = click_count; + event.data.mouse.x = mshook->pt.x; + event.data.mouse.y = mshook->pt.y; + + logger(LOG_LEVEL_INFO, "%s [%u]: Mouse %s to %u, %u.\n", + __FUNCTION__, __LINE__, mouse_dragged ? "dragged" : "moved", + event.data.mouse.x, event.data.mouse.y); + + // Fire mouse move event. + dispatch_event(&event); + } +} + +static void process_mouse_wheel(MSLLHOOKSTRUCT *mshook, uint8_t direction) { + // Track the number of clicks. + // Reset the click count and previous button. + click_count = 1; + click_button = MOUSE_NOBUTTON; + + // Populate mouse wheel event. + event.time = GetMessageTime(); + event.reserved = 0x00; + + event.type = EVENT_MOUSE_WHEEL; + event.mask = get_modifiers(); + + event.data.wheel.clicks = click_count; + event.data.wheel.x = mshook->pt.x; + event.data.wheel.y = mshook->pt.y; + + event.data.wheel.type = get_scroll_wheel_type(); + event.data.wheel.amount = get_scroll_wheel_amount(); + + /* Delta HIWORD(mshook->mouseData) + * A positive value indicates that the wheel was rotated + * forward, away from the user; a negative value indicates that + * the wheel was rotated backward, toward the user. One wheel + * click is defined as WHEEL_DELTA, which is 120. */ + event.data.wheel.rotation = ((int16_t) HIWORD(mshook->mouseData) / WHEEL_DELTA) * -1; + + // Set the direction based on what event was received. + event.data.wheel.direction = direction; + + logger(LOG_LEVEL_INFO, "%s [%u]: Mouse wheel type %u, rotated %i units in the %u direction at %u, %u.\n", + __FUNCTION__, __LINE__, event.data.wheel.type, + event.data.wheel.amount * event.data.wheel.rotation, + event.data.wheel.direction, + event.data.wheel.x, event.data.wheel.y); + + // Fire mouse wheel event. + dispatch_event(&event); +} + +LRESULT CALLBACK mouse_hook_event_proc(int nCode, WPARAM wParam, LPARAM lParam) { + MSLLHOOKSTRUCT *mshook = (MSLLHOOKSTRUCT *) lParam; + switch (wParam) { + case WM_LBUTTONDOWN: + set_modifier_mask(MASK_BUTTON1); + process_button_pressed(mshook, MOUSE_BUTTON1); + break; + + case WM_RBUTTONDOWN: + set_modifier_mask(MASK_BUTTON2); + process_button_pressed(mshook, MOUSE_BUTTON2); + break; + + case WM_MBUTTONDOWN: + set_modifier_mask(MASK_BUTTON3); + process_button_pressed(mshook, MOUSE_BUTTON3); + break; + + case WM_XBUTTONDOWN: + case WM_NCXBUTTONDOWN: + if (HIWORD(mshook->mouseData) == XBUTTON1) { + set_modifier_mask(MASK_BUTTON4); + process_button_pressed(mshook, MOUSE_BUTTON4); + } + else if (HIWORD(mshook->mouseData) == XBUTTON2) { + set_modifier_mask(MASK_BUTTON5); + process_button_pressed(mshook, MOUSE_BUTTON5); + } + else { + // Extra mouse buttons. + uint16_t button = HIWORD(mshook->mouseData); + + // Add support for mouse 4 & 5. + if (button == 4) { + set_modifier_mask(MOUSE_BUTTON4); + } + else if (button == 5) { + set_modifier_mask(MOUSE_BUTTON5); + } + + process_button_pressed(mshook, button); + } + break; + + + case WM_LBUTTONUP: + unset_modifier_mask(MASK_BUTTON1); + process_button_released(mshook, MOUSE_BUTTON1); + break; + + case WM_RBUTTONUP: + unset_modifier_mask(MASK_BUTTON2); + process_button_released(mshook, MOUSE_BUTTON2); + break; + + case WM_MBUTTONUP: + unset_modifier_mask(MASK_BUTTON3); + process_button_released(mshook, MOUSE_BUTTON3); + break; + + case WM_XBUTTONUP: + case WM_NCXBUTTONUP: + if (HIWORD(mshook->mouseData) == XBUTTON1) { + unset_modifier_mask(MASK_BUTTON4); + process_button_released(mshook, MOUSE_BUTTON4); + } + else if (HIWORD(mshook->mouseData) == XBUTTON2) { + unset_modifier_mask(MASK_BUTTON5); + process_button_released(mshook, MOUSE_BUTTON5); + } + else { + // Extra mouse buttons. + uint16_t button = HIWORD(mshook->mouseData); + + // Add support for mouse 4 & 5. + if (button == 4) { + unset_modifier_mask(MOUSE_BUTTON4); + } + else if (button == 5) { + unset_modifier_mask(MOUSE_BUTTON5); + } + + process_button_released(mshook, MOUSE_BUTTON5); + } + break; + + case WM_MOUSEMOVE: + process_mouse_moved(mshook); + break; + + case WM_MOUSEWHEEL: + process_mouse_wheel(mshook, WHEEL_VERTICAL_DIRECTION); + break; + + /* For horizontal scroll wheel support. + * NOTE Windows >= Vista + * case 0x020E: + */ + case WM_MOUSEHWHEEL: + process_mouse_wheel(mshook, WHEEL_HORIZONTAL_DIRECTION); + break; + + default: + // In theory this *should* never execute. + logger(LOG_LEVEL_DEBUG, "%s [%u]: Unhandled Windows mouse event: %#X.\n", + __FUNCTION__, __LINE__, (unsigned int) wParam); + break; + } + + LRESULT hook_result = -1; + if (nCode < 0 || event.reserved ^ 0x01) { + hook_result = CallNextHookEx(mouse_event_hhook, nCode, wParam, lParam); + } + else { + logger(LOG_LEVEL_DEBUG, "%s [%u]: Consuming the current event. (%li)\n", + __FUNCTION__, __LINE__, (long) hook_result); + } + + return hook_result; +} + + +// Callback function that handles events. +void CALLBACK win_hook_event_proc(HWINEVENTHOOK hook, DWORD event, HWND hWnd, LONG idObject, LONG idChild, DWORD dwEventThread, DWORD dwmsEventTime) { + switch (event) { + case EVENT_OBJECT_NAMECHANGE: + logger(LOG_LEVEL_INFO, "%s [%u]: Restarting Windows input hook on window event: %#X.\n", + __FUNCTION__, __LINE__, event); + + // Remove any keyboard or mouse hooks that are still running. + if (keyboard_event_hhook != NULL) { + UnhookWindowsHookEx(keyboard_event_hhook); + } + + if (mouse_event_hhook != NULL) { + UnhookWindowsHookEx(mouse_event_hhook); + } + + // Restart the event hooks. + keyboard_event_hhook = SetWindowsHookEx(WH_KEYBOARD_LL, keyboard_hook_event_proc, hInst, 0); + mouse_event_hhook = SetWindowsHookEx(WH_MOUSE_LL, mouse_hook_event_proc, hInst, 0); + + // Re-initialize modifier masks. + initialize_modifiers(); + + // FIXME We should compare the modifier mask before and after the restart + // to determine if we should synthesize missing events. + + // Check for event hook error. + if (keyboard_event_hhook == NULL || mouse_event_hhook == NULL) { + logger(LOG_LEVEL_ERROR, "%s [%u]: SetWindowsHookEx() failed! (%#lX)\n", + __FUNCTION__, __LINE__, (unsigned long) GetLastError()); + } + break; + + default: + logger(LOG_LEVEL_INFO, "%s [%u]: Unhandled Windows window event: %#X.\n", + __FUNCTION__, __LINE__, event); + } +} + + +IOHOOK_API int hook_run() { + int status = IOHOOK_FAILURE; + + // Set the thread id we want to signal later. + hook_thread_id = GetCurrentThreadId(); + + // Spot check the hInst incase the library was statically linked and DllMain + // did not receive a pointer on load. + if (hInst == NULL) { + logger(LOG_LEVEL_INFO, "%s [%u]: hInst was not set by DllMain().\n", + __FUNCTION__, __LINE__); + + hInst = GetModuleHandle(NULL); + if (hInst != NULL) { + // Initialize native input helper functions. + load_input_helper(); + } + else { + logger(LOG_LEVEL_ERROR, "%s [%u]: Could not determine hInst for SetWindowsHookEx()! (%#lX)\n", + __FUNCTION__, __LINE__, (unsigned long) GetLastError()); + + status = IOHOOK_ERROR_GET_MODULE_HANDLE; + } + } + + // Create the native hooks. + keyboard_event_hhook = SetWindowsHookEx(WH_KEYBOARD_LL, keyboard_hook_event_proc, hInst, 0); + mouse_event_hhook = SetWindowsHookEx(WH_MOUSE_LL, mouse_hook_event_proc, hInst, 0); + + // Create a window event hook to listen for capture change. + win_event_hhook = SetWinEventHook( + EVENT_OBJECT_NAMECHANGE, EVENT_OBJECT_NAMECHANGE, + NULL, + win_hook_event_proc, + 0, 0, + WINEVENT_OUTOFCONTEXT | WINEVENT_SKIPOWNPROCESS); + + // If we did not encounter a problem, start processing events. + if (keyboard_event_hhook != NULL && mouse_event_hhook != NULL) { + if (win_event_hhook == NULL) { + logger(LOG_LEVEL_WARN, "%s [%u]: SetWinEventHook() failed!\n", + __FUNCTION__, __LINE__); + } + + logger(LOG_LEVEL_DEBUG, "%s [%u]: SetWindowsHookEx() successful.\n", + __FUNCTION__, __LINE__); + + // Check and setup modifiers. + initialize_modifiers(); + + // Set the exit status. + status = IOHOOK_SUCCESS; + + // Windows does not have a hook start event or callback so we need to + // manually fake it. + hook_start_proc(); + + // Block until the thread receives an WM_QUIT request. + MSG message; + while (GetMessage(&message, (HWND) NULL, 0, 0) > 0) { + TranslateMessage(&message); + DispatchMessage(&message); + } + } + else { + logger(LOG_LEVEL_ERROR, "%s [%u]: SetWindowsHookEx() failed! (%#lX)\n", + __FUNCTION__, __LINE__, (unsigned long) GetLastError()); + + status = IOHOOK_ERROR_SET_WINDOWS_HOOK_EX; + } + + + // Unregister any hooks that may still be installed. + unregister_running_hooks(); + + // We must explicitly call the cleanup handler because Windows does not + // provide a thread cleanup method like POSIX pthread_cleanup_push/pop. + hook_stop_proc(); + + return status; +} + +IOHOOK_API int hook_stop() { + int status = IOHOOK_FAILURE; + + // Try to exit the thread naturally. + if (PostThreadMessage(hook_thread_id, WM_QUIT, (WPARAM) NULL, (LPARAM) NULL)) { + status = IOHOOK_SUCCESS; + } + + logger(LOG_LEVEL_DEBUG, "%s [%u]: Status: %#X.\n", + __FUNCTION__, __LINE__, status); + + return status; +} diff --git a/vendor/github.com/robotn/gohook/hook/windows/input.h b/vendor/github.com/robotn/gohook/hook/windows/input.h new file mode 100644 index 0000000..6ba9817 --- /dev/null +++ b/vendor/github.com/robotn/gohook/hook/windows/input.h @@ -0,0 +1,104 @@ +/*********************************************************************** + Input + ***********************************************************************/ + +#ifndef _included_input_helper +#define _included_input_helper + +#include +#include + +#ifndef LPFN_ISWOW64PROCESS +typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL); +#endif + +typedef void* (CALLBACK *KbdLayerDescriptor) (VOID); + +#define CAPLOK 0x01 +#define WCH_NONE 0xF000 +#define WCH_DEAD 0xF001 + +#ifndef WM_MOUSEHWHEEL +#define WM_MOUSEHWHEEL 0x020E +#endif + +typedef struct _VK_TO_WCHARS { + BYTE VirtualKey; + BYTE Attributes; + WCHAR wch[]; +} VK_TO_WCHARS, *PVK_TO_WCHARS; + +typedef struct _LIGATURE { + BYTE VirtualKey; + WORD ModificationNumber; + WCHAR wch[]; +} LIGATURE, *PLIGATURE; + +typedef struct _VK_TO_BIT { + BYTE Vk; + BYTE ModBits; +} VK_TO_BIT, *PVK_TO_BIT; + +typedef struct _MODIFIERS { + PVK_TO_BIT pVkToBit; // __ptr64 + WORD wMaxModBits; + BYTE ModNumber[]; +} MODIFIERS, *PMODIFIERS; + +typedef struct _VSC_VK { + BYTE Vsc; + USHORT Vk; +} VSC_VK, *PVSC_VK; + +typedef struct _VK_TO_WCHAR_TABLE { + PVK_TO_WCHARS pVkToWchars; // __ptr64 + BYTE nModifications; + BYTE cbSize; +} VK_TO_WCHAR_TABLE, *PVK_TO_WCHAR_TABLE; + +typedef struct _DEADKEY { + DWORD dwBoth; + WCHAR wchComposed; + USHORT uFlags; +} DEADKEY, *PDEADKEY; + +typedef struct _VSC_LPWSTR { + BYTE vsc; + WCHAR *pwsz; // __ptr64 +} VSC_LPWSTR, *PVSC_LPWSTR; + +typedef struct tagKbdLayer { + PMODIFIERS pCharModifiers; // __ptr64 + PVK_TO_WCHAR_TABLE pVkToWcharTable; // __ptr64 + PDEADKEY pDeadKey; // __ptr64 + PVSC_LPWSTR pKeyNames; // __ptr64 + PVSC_LPWSTR pKeyNamesExt; // __ptr64 + WCHAR **pKeyNamesDead; // __ptr64 + USHORT *pusVSCtoVK; // __ptr64 + BYTE bMaxVSCtoVK; + PVSC_VK pVSCtoVK_E0; // __ptr64 + PVSC_VK pVSCtoVK_E1; // __ptr64 + DWORD fLocaleFlags; + BYTE nLgMax; + BYTE cbLgEntry; + PLIGATURE pLigature; // __ptr64 + DWORD dwType; + DWORD dwSubType; +} KBDTABLES, *PKBDTABLES; // __ptr64 + + +extern SIZE_T keycode_to_unicode(DWORD keycode, PWCHAR buffer, SIZE_T size); + +//extern DWORD unicode_to_keycode(wchar_t unicode); + +extern unsigned short keycode_to_scancode(DWORD vk_code, DWORD flags); + +extern DWORD scancode_to_keycode(unsigned short scancode); + +// Initialize the locale list and wow64 pointer size. +extern int load_input_helper(); + +// Cleanup the initialized locales. +extern int unload_input_helper(); + +#endif diff --git a/vendor/github.com/robotn/gohook/hook/windows/input_c.h b/vendor/github.com/robotn/gohook/hook/windows/input_c.h new file mode 100644 index 0000000..f061b1b --- /dev/null +++ b/vendor/github.com/robotn/gohook/hook/windows/input_c.h @@ -0,0 +1,832 @@ + +#ifdef HAVE_CONFIG_H + #include +#endif + +#include +#include +#include +#include +#include +#include + +#include "../iohook.h" +#include "../logger_c.h" +#include "input.h" + +static const uint16_t keycode_scancode_table[][2] = { + /* idx { vk_code, scancode }, */ + /* 0 */ { VC_UNDEFINED, 0x0000 }, // 0x00 + /* 1 */ { MOUSE_BUTTON1, VK_ESCAPE }, // 0x01 + /* 2 */ { MOUSE_BUTTON2, 0x0031 }, // 0x02 + /* 3 */ { VC_UNDEFINED, 0x0032 }, // 0x03 VK_CANCEL + /* 4 */ { MOUSE_BUTTON3, 0x0033 }, // 0x04 + /* 5 */ { MOUSE_BUTTON4, 0x0034 }, // 0x05 + /* 6 */ { MOUSE_BUTTON5, 0x0035 }, // 0x06 + /* 7 */ { VC_UNDEFINED, 0x0036 }, // 0x07 Undefined + /* 8 */ { VC_BACKSPACE, 0x0037 }, // 0x08 VK_BACK + /* 9 */ { VC_TAB, 0x0038 }, // 0x09 VK_TAB + /* 10 */ { VC_UNDEFINED, 0x0039 }, // 0x0A Reserved + /* 11 */ { VC_UNDEFINED, 0x0030 }, // 0x0B Reserved + /* 12 */ { VC_CLEAR, VK_OEM_MINUS }, // 0x0C VK_CLEAR + /* 13 */ { VC_ENTER, VK_OEM_PLUS }, // 0x0D VK_RETURN + /* 14 */ { VC_UNDEFINED, VK_BACK }, // 0x0E Undefined + /* 15 */ { VC_UNDEFINED, VK_TAB }, // 0x0F Undefined + /* 16 */ { VC_SHIFT_L, 0x0051 }, // 0x10 VK_SHIFT + /* 17 */ { VC_CONTROL_L, 0x0057 }, // 0x11 VK_CONTROL + /* 18 */ { VC_ALT_L, 0x0045 }, // 0x12 VK_MENU ALT key + /* 19 */ { VC_PAUSE, 0x0052 }, // 0x13 VK_PAUSE + /* 20 */ { VC_CAPS_LOCK, 0x0054 }, // 0x14 VK_CAPITAL CAPS LOCK key + /* 21 */ { VC_KATAKANA, 0x0059 }, // 0x15 VK_KANA IME Kana mode + /* 22 */ { VC_UNDEFINED, 0x0055 }, // 0x16 Undefined + /* 23 */ { VC_UNDEFINED, 0x0049 }, // 0x17 VK_JUNJA IME Junja mode + /* 24 */ { VC_UNDEFINED, 0x004F }, // 0x18 VK_FINAL + /* 25 */ { VC_KANJI, 0x0050 }, // 0x19 VK_KANJI / VK_HANJA IME Kanji / Hanja mode + /* 26 */ { VC_UNDEFINED, 0x00DB }, // 0x1A Undefined + /* 27 */ { VC_ESCAPE, 0x00DD }, // 0x1B VK_ESCAPE ESC key + /* 28 */ { VC_UNDEFINED, VK_RETURN }, // 0x1C VK_CONVERT IME convert// 0x1C + /* 29 */ { VC_UNDEFINED, VK_LCONTROL }, // 0x1D VK_NONCONVERT IME nonconvert + /* 30 */ { VC_UNDEFINED, 0x0041 }, // 0x1E VK_ACCEPT IME accept + /* 31 */ { VC_UNDEFINED, 0x0053 }, // 0x1F VK_MODECHANGE IME mode change request + /* 32 */ { VC_SPACE, 0x0044 }, // 0x20 VK_SPACE SPACEBAR + /* 33 */ { VC_PAGE_UP, 0x0046 }, // 0x21 VK_PRIOR PAGE UP key + /* 34 */ { VC_PAGE_DOWN, 0x0047 }, // 0x22 VK_NEXT PAGE DOWN key + /* 35 */ { VC_END, 0x0048 }, // 0x23 VK_END END key + /* 36 */ { VC_HOME, 0x004A }, // 0x24 VK_HOME HOME key + /* 37 */ { VC_LEFT, 0x004B }, // 0x25 VK_LEFT LEFT ARROW key + /* 38 */ { VC_UP, 0x004C }, // 0x26 VK_UP UP ARROW key + /* 39 */ { VC_RIGHT, VK_OEM_1 }, // 0x27 VK_RIGHT RIGHT ARROW key + /* 40 */ { VC_DOWN, VK_OEM_7 }, // 0x28 VK_DOWN DOWN ARROW key + /* 41 */ { VC_UNDEFINED, VK_OEM_3 }, // 0x29 VK_SELECT SELECT key + /* 42 */ { VC_UNDEFINED, VK_LSHIFT }, // 0x2A VK_PRINT PRINT key + /* 43 */ { VC_UNDEFINED, VK_OEM_5 }, // 0x2B VK_EXECUTE EXECUTE key + /* 44 */ { VC_PRINTSCREEN, 0x005A }, // 0x2C VK_SNAPSHOT PRINT SCREEN key + /* 45 */ { VC_INSERT, 0x0058 }, // 0x2D VK_INSERT INS key + /* 46 */ { VC_DELETE, 0x0043 }, // 0x2E VK_DELETE DEL key + /* 47 */ { VC_UNDEFINED, 0x0056 }, // 0x2F VK_HELP HELP key + /* 48 */ { VC_0, 0x0042 }, // 0x30 0 key + /* 49 */ { VC_1, 0x004E }, // 0x31 1 key + /* 50 */ { VC_2, 0x004D }, // 0x32 2 key + /* 51 */ { VC_3, VK_OEM_COMMA }, // 0x33 3 key + /* 52 */ { VC_4, VK_OEM_PERIOD }, // 0x34 4 key + /* 53 */ { VC_5, VK_OEM_2 }, // 0x35 5 key + /* 54 */ { VC_6, VK_RSHIFT }, // 0x36 6 key + /* 55 */ { VC_7, VK_MULTIPLY }, // 0x37 7 key + /* 56 */ { VC_8, VK_LMENU }, // 0x38 8 key + /* 57 */ { VC_9, VK_SPACE }, // 0x39 9 key + /* 58 */ { VC_UNDEFINED, VK_CAPITAL }, // 0x3A Undefined + /* 59 */ { VC_UNDEFINED, VK_F1 }, // 0x3B Undefined + /* 60 */ { VC_UNDEFINED, VK_F2 }, // 0x3C Undefined + /* 61 */ { VC_UNDEFINED, VK_F3 }, // 0x3D Undefined + /* 62 */ { VC_UNDEFINED, VK_F4 }, // 0x3E Undefined + /* 63 */ { VC_UNDEFINED, VK_F5 }, // 0x3F Undefined + /* 64 */ { VC_UNDEFINED, VK_F6 }, // 0x40 Undefined + /* 65 */ { VC_A, VK_F7 }, // 0x41 A key + /* 66 */ { VC_B, VK_F8 }, // 0x42 B key + /* 67 */ { VC_C, VK_F9 }, // 0x43 C key + /* 68 */ { VC_D, VK_F10 }, // 0x44 D key + /* 69 */ { VC_E, VK_NUMLOCK }, // 0x45 E key + /* 70 */ { VC_F, VK_SCROLL }, // 0x46 F key + /* 71 */ { VC_G, VK_NUMPAD7 }, // 0x47 G key + /* 72 */ { VC_H, VK_NUMPAD8 }, // 0x48 H key + /* 73 */ { VC_I, VK_NUMPAD9 }, // 0x49 I key + /* 74 */ { VC_J, VK_SUBTRACT }, // 0x4A J key + /* 75 */ { VC_K, VK_NUMPAD4 }, // 0x4B K key + /* 76 */ { VC_L, VK_NUMPAD5 }, // 0x4C L key + /* 77 */ { VC_M, VK_NUMPAD6 }, // 0x4D M key + /* 78 */ { VC_N, VK_ADD }, // 0x4E N key + /* 79 */ { VC_O, VK_NUMPAD1 }, // 0x4F O key + /* 80 */ { VC_P, VK_NUMPAD2 }, // 0x50 P key + /* 81 */ { VC_Q, VK_NUMPAD3 }, // 0x51 Q key + /* 82 */ { VC_R, VK_NUMPAD0 }, // 0x52 R key + /* 83 */ { VC_S, VK_DECIMAL }, // 0x53 S key + /* 84 */ { VC_T, 0x0000 }, // 0x54 T key + /* 85 */ { VC_U, 0x0000 }, // 0x55 U key + /* 86 */ { VC_V, 0x0000 }, // 0x56 V key + /* 87 */ { VC_W, VK_F11 }, // 0x57 W key + /* 88 */ { VC_X, VK_F12 }, // 0x58 X key + /* 89 */ { VC_Y, 0x0000 }, // 0x59 Y key + /* 90 */ { VC_Z, 0x0000 }, // 0x5A Z key + /* 91 */ { VC_META_L, VK_F13 }, // 0x5B VK_LWIN Left Windows key (Natural keyboard) + /* 92 */ { VC_META_R, VK_F14 }, // 0x5C VK_RWIN Right Windows key (Natural keyboard) + /* 93 */ { VC_CONTEXT_MENU, VK_F15 }, // 0x5D VK_APPS Applications key (Natural keyboard) + /* 94 */ { VC_UNDEFINED, 0x0000 }, // 0x5E Reserved + /* 95 */ { VC_SLEEP, 0x0000 }, // 0x5F VK_SLEEP Computer Sleep key + /* 96 */ { VC_KP_0, 0x0000 }, // 0x60 VK_NUMPAD0 Numeric keypad 0 key + /* 97 */ { VC_KP_1, 0x0000 }, // 0x61 VK_NUMPAD1 Numeric keypad 1 key + /* 98 */ { VC_KP_2, 0x0000 }, // 0x62 VK_NUMPAD2 Numeric keypad 2 key + /* 99 */ { VC_KP_3, VK_F16 }, // 0x63 VK_NUMPAD3 Numeric keypad 3 key + /* 100 */ { VC_KP_4, VK_F17 }, // 0x64 VK_NUMPAD4 Numeric keypad 4 key + /* 101 */ { VC_KP_5, VK_F18 }, // 0x65 VK_NUMPAD5 Numeric keypad 5 key + /* 102 */ { VC_KP_6, VK_F19 }, // 0x66 VK_NUMPAD6 Numeric keypad 6 key + /* 103 */ { VC_KP_7, VK_F20 }, // 0x67 VK_NUMPAD7 Numeric keypad 7 key + /* 104 */ { VC_KP_8, VK_F21 }, // 0x68 VK_NUMPAD8 Numeric keypad 8 key + /* 105 */ { VC_KP_9, VK_F22 }, // 0x69 VK_NUMPAD9 Numeric keypad 9 key + /* 106 */ { VC_KP_MULTIPLY, VK_F23 }, // 0x6A VK_MULTIPLY Multiply key + /* 107 */ { VC_KP_ADD, VK_F24 }, // 0x6B VK_ADD Add key + /* 108 */ { VC_UNDEFINED, 0x0000 }, // 0x6C VK_SEPARATOR Separator key + /* 109 */ { VC_KP_SUBTRACT, 0x0000 }, // 0x6D VK_SUBTRACT Subtract key + /* 110 */ { VC_KP_SEPARATOR, 0x0000 }, // 0x6E VK_DECIMAL Decimal key + /* 111 */ { VC_KP_DIVIDE, 0x0000 }, // 0x6F VK_DIVIDE Divide key + /* 112 */ { VC_F1, VK_KANA }, // 0x70 VK_F1 F1 key + /* 113 */ { VC_F2, 0x0000 }, // 0x71 VK_F2 F2 key + /* 114 */ { VC_F3, 0x0000 }, // 0x72 VK_F3 F3 key + /* 115 */ { VC_F4, 0x0000 }, // 0x73 VK_F4 F4 key + /* 116 */ { VC_F5, 0x0000 }, // 0x74 VK_F5 F5 key + /* 117 */ { VC_F6, 0x0000 }, // 0x75 VK_F6 F6 key + /* 118 */ { VC_F7, 0x0000 }, // 0x76 VK_F7 F7 key + /* 119 */ { VC_F8, 0x0000 }, // 0x77 VK_F8 F8 key + /* 120 */ { VC_F9, 0x0000 }, // 0x78 VK_F9 F9 key + /* 121 */ { VC_F10, VK_KANJI }, // 0x79 VK_F10 F10 key + /* 122 */ { VC_F11, 0x0000 }, // 0x7A VK_F11 F11 key + /* 123 */ { VC_F12, 0x0000 }, // 0x7B VK_F12 F12 key + /* 124 */ { VC_F13, 0x0000 }, // 0x7C VK_F13 F13 key + /* 125 */ { VC_F14, VK_OEM_8 }, // 0x7D VK_F14 F14 key + /* 126 */ { VC_F15, 0x0000 }, // 0x7E VK_F15 F15 key + /* 127 */ { VC_F16, 0x0000 }, // 0x7F VK_F16 F16 key + + // No Offset Offset (i & 0x007F) | 0x80 + + /* 128 */ { VC_F17, 0x0000 }, // 0x80 VK_F17 F17 key + /* 129 */ { VC_F18, 0x0000 }, // 0x81 VK_F18 F18 key + /* 130 */ { VC_F19, 0x0000 }, // 0x82 VK_F19 F19 key + /* 131 */ { VC_F20, 0x0000 }, // 0x83 VK_F20 F20 key + /* 132 */ { VC_F21, 0x0000 }, // 0x84 VK_F21 F21 key + /* 133 */ { VC_F22, 0x0000 }, // 0x85 VK_F22 F22 key + /* 134 */ { VC_F23, 0x0000 }, // 0x86 VK_F23 F23 key + /* 135 */ { VC_F24, 0x0000 }, // 0x87 VK_F24 F24 key + /* 136 */ { VC_UNDEFINED, 0x0000 }, // 0x88 Unassigned + /* 137 */ { VC_UNDEFINED, 0x0000 }, // 0x89 Unassigned + /* 138 */ { VC_UNDEFINED, 0x0000 }, // 0x8A Unassigned + /* 139 */ { VC_UNDEFINED, 0x0000 }, // 0x8B Unassigned + /* 140 */ { VC_UNDEFINED, 0x0000 }, // 0x8C Unassigned + /* 141 */ { VC_UNDEFINED, 0x0000 }, // 0x8D Unassigned + /* 142 */ { VC_UNDEFINED, 0x0000 }, // 0x8E Unassigned + /* 143 */ { VC_UNDEFINED, 0x0000 }, // 0x8F Unassigned + /* 144 */ { VC_NUM_LOCK, VK_MEDIA_PREV_TRACK }, // 0x90 VK_NUMLOCK NUM LOCK key + /* 145 */ { VC_SCROLL_LOCK, 0x0000 }, // 0x91 VK_SCROLL SCROLL LOCK key + /* 146 */ { VC_UNDEFINED, 0x0000 }, // 0x92 OEM specific + /* 147 */ { VC_UNDEFINED, 0x0000 }, // 0x93 OEM specific + /* 148 */ { VC_UNDEFINED, 0x0000 }, // 0x94 OEM specific + /* 149 */ { VC_UNDEFINED, 0x0000 }, // 0x95 OEM specific + /* 150 */ { VC_UNDEFINED, 0x0000 }, // 0x96 OEM specific + /* 151 */ { VC_UNDEFINED, 0x0000 }, // 0x97 Unassigned + /* 152 */ { VC_UNDEFINED, 0x0000 }, // 0x98 Unassigned + /* 153 */ { VC_UNDEFINED, VK_MEDIA_NEXT_TRACK }, // 0x99 Unassigned + /* 154 */ { VC_UNDEFINED, 0x0000 }, // 0x9A Unassigned + /* 155 */ { VC_UNDEFINED, 0x0000 }, // 0x9B Unassigned + /* 156 */ { VC_UNDEFINED, 0x0000 }, // 0x9C Unassigned + /* 157 */ { VC_UNDEFINED, VK_RCONTROL }, // 0x9D Unassigned + /* 158 */ { VC_UNDEFINED, 0x0000 }, // 0x9E Unassigned + /* 159 */ { VC_UNDEFINED, 0x0000 }, // 0x9F Unassigned + /* 160 */ { VC_SHIFT_L, VK_VOLUME_MUTE }, // 0xA0 VK_LSHIFT Left SHIFT key + /* 161 */ { VC_SHIFT_R, VK_LAUNCH_APP2 }, // 0xA1 VK_RSHIFT Right SHIFT key + /* 162 */ { VC_CONTROL_L, VK_MEDIA_PLAY_PAUSE }, // 0xA2 VK_LCONTROL Left CONTROL key + /* 163 */ { VC_CONTROL_R, 0x0000 }, // 0xA3 VK_RCONTROL Right CONTROL key + /* 164 */ { VC_ALT_L, VK_MEDIA_STOP }, // 0xA4 VK_LMENU Left MENU key + /* 165 */ { VC_ALT_R, 0x0000 }, // 0xA5 VK_RMENU Right MENU key + /* 166 */ { VC_BROWSER_BACK, 0x0000 }, // 0xA6 VK_BROWSER_BACK Browser Back key + /* 167 */ { VC_BROWSER_FORWARD, 0x0000 }, // 0xA7 VK_BROWSER_FORWARD Browser Forward key + /* 168 */ { VC_BROWSER_REFRESH, 0x0000 }, // 0xA8 VK_BROWSER_REFRESH Browser Refresh key + /* 169 */ { VC_BROWSER_STOP, 0x0000 }, // 0xA9 VK_BROWSER_STOP Browser Stop key + /* 170 */ { VC_BROWSER_SEARCH, 0x0000 }, // 0xAA VK_BROWSER_SEARCH Browser Search key + /* 171 */ { VC_BROWSER_FAVORITES, 0x0000 }, // 0xAB VK_BROWSER_FAVORITES Browser Favorites key + /* 172 */ { VC_BROWSER_HOME, 0x0000 }, // 0xAC VK_BROWSER_HOME Browser Start and Home key + /* 173 */ { VC_VOLUME_MUTE, 0x0000 }, // 0xAD VK_VOLUME_MUTE Volume Mute key + /* 174 */ { VC_VOLUME_DOWN, VK_VOLUME_DOWN }, // 0xAE VK_VOLUME_DOWN Volume Down key + /* 175 */ { VC_VOLUME_UP, 0x0000 }, // 0xAF VK_VOLUME_UP Volume Up key + /* 176 */ { VC_MEDIA_NEXT, VK_VOLUME_UP }, // 0xB0 VK_MEDIA_NEXT_TRACK Next Track key + /* 177 */ { VC_MEDIA_PREVIOUS, 0x0000 }, // 0xB1 VK_MEDIA_PREV_TRACK Previous Track key + /* 178 */ { VC_MEDIA_STOP, VK_BROWSER_HOME }, // 0xB2 VK_MEDIA_STOP Stop Media key + /* 179 */ { VC_MEDIA_PLAY, 0x0000 }, // 0xB3 VK_MEDIA_PLAY_PAUSE Play/Pause Media key + /* 180 */ { VC_UNDEFINED, 0x0000 }, // 0xB4 VK_LAUNCH_MAIL Start Mail key + /* 181 */ { VC_MEDIA_SELECT, VK_DIVIDE }, // 0xB5 VK_LAUNCH_MEDIA_SELECT Select Media key + /* 182 */ { VC_APP_MAIL, 0x0000 }, // 0xB6 VK_LAUNCH_APP1 Start Application 1 key + /* 183 */ { VC_APP_CALCULATOR, VK_SNAPSHOT }, // 0xB7 VK_LAUNCH_APP2 Start Application 2 key + /* 184 */ { VC_UNDEFINED, VK_RMENU }, // 0xB8 Reserved + /* 185 */ { VC_UNDEFINED, 0x0000 }, // 0xB9 Reserved + /* 186 */ { VC_SEMICOLON, 0x0000 }, // 0xBA VK_OEM_1 Varies by keyboard. For the US standard keyboard, the ';:' key + /* 187 */ { VC_EQUALS, 0x0000 }, // 0xBB VK_OEM_PLUS For any country/region, the '+' key + /* 188 */ { VC_COMMA, 0x00E6 }, // 0xBC VK_OEM_COMMA For any country/region, the ',' key + /* 189 */ { VC_MINUS, 0x0000 }, // 0xBD VK_OEM_MINUS For any country/region, the '-' key + /* 190 */ { VC_PERIOD, 0x0000 }, // 0xBE VK_OEM_PERIOD For any country/region, the '.' key + /* 191 */ { VC_SLASH, 0x0000 }, // 0xBF VK_OEM_2 Varies by keyboard. For the US standard keyboard, the '/?' key + /* 192 */ { VC_BACKQUOTE, 0x0000 }, // 0xC0 VK_OEM_3 Varies by keyboard. For the US standard keyboard, the '`~' key + /* 193 */ { VC_UNDEFINED, 0x0000 }, // 0xC1 Reserved + /* 194 */ { VC_UNDEFINED, 0x0000 }, // 0xC2 Reserved + /* 195 */ { VC_UNDEFINED, 0x0000 }, // 0xC3 Reserved + /* 196 */ { VC_UNDEFINED, 0x0000 }, // 0xC4 Reserved + /* 197 */ { VC_UNDEFINED, VK_PAUSE }, // 0xC5 Reserved + /* 198 */ { VC_UNDEFINED, 0x0000 }, // 0xC6 Reserved + /* 199 */ { VC_UNDEFINED, VK_HOME }, // 0xC7 Reserved + /* 200 */ { VC_UNDEFINED, VK_UP }, // 0xC8 Reserved + /* 201 */ { VC_UNDEFINED, VK_PRIOR }, // 0xC9 Reserved + /* 202 */ { VC_UNDEFINED, 0x0000 }, // 0xCA Reserved + /* 203 */ { VC_UNDEFINED, VK_LEFT }, // 0xCB Reserved + /* 204 */ { VC_UNDEFINED, VK_CLEAR }, // 0xCC Reserved + /* 205 */ { VC_UNDEFINED, VK_RIGHT }, // 0xCD Reserved + /* 206 */ { VC_UNDEFINED, 0x0000 }, // 0xCE Reserved + /* 207 */ { VC_UNDEFINED, VK_END }, // 0xCF Reserved + /* 208 */ { VC_UNDEFINED, VK_DOWN }, // 0xD0 Reserved + /* 209 */ { VC_UNDEFINED, VK_NEXT }, // 0xD1 Reserved + /* 210 */ { VC_UNDEFINED, VK_INSERT }, // 0xD2 Reserved + /* 211 */ { VC_UNDEFINED, VK_DELETE }, // 0xD3 Reserved + /* 212 */ { VC_UNDEFINED, 0x0000 }, // 0xD4 Reserved + /* 213 */ { VC_UNDEFINED, 0x0000 }, // 0xD5 Reserved + /* 214 */ { VC_UNDEFINED, 0x0000 }, // 0xD6 Reserved + /* 215 */ { VC_UNDEFINED, 0x0000 }, // 0xD7 Reserved + /* 216 */ { VC_UNDEFINED, 0x0000 }, // 0xD8 Unassigned + /* 217 */ { VC_UNDEFINED, 0x0000 }, // 0xD9 Unassigned + /* 218 */ { VC_UNDEFINED, 0x0000 }, // 0xDA Unassigned + /* 219 */ { VC_OPEN_BRACKET, VK_LWIN }, // 0xDB VK_OEM_4 Varies by keyboard. For the US standard keyboard, the '[{' key + /* 220 */ { VC_BACK_SLASH, VK_RWIN }, // 0xDC VK_OEM_5 Varies by keyboard. For the US standard keyboard, the '\|' key + /* 221 */ { VC_CLOSE_BRACKET, VK_APPS }, // 0xDD VK_OEM_6 Varies by keyboard. For the US standard keyboard, the ']}' key + /* 222 */ { VC_QUOTE, 0x0000 }, // 0xDE VK_OEM_7 Varies by keyboard. For the US standard keyboard, the 'single-quote/double-quote' key + /* 223 */ { VC_YEN, VK_SLEEP }, // 0xDF VK_OEM_8 Varies by keyboard. + /* 224 */ { VC_UNDEFINED, 0x0000 }, // 0xE0 Reserved + /* 225 */ { VC_UNDEFINED, 0x0000 }, // 0xE1 OEM specific + /* 226 */ { VC_UNDEFINED, 0x0000 }, // 0xE2 VK_OEM_102 Either the angle bracket key or the backslash key on the RT 102-key keyboard + /* 227 */ { VC_UNDEFINED, 0x0000 }, // 0xE3 OEM specific + /* 228 */ { VC_UNDEFINED, 0x00E5 }, // 0xE4 VC_APP_PICTURES OEM specific + /* 229 */ { VC_APP_PICTURES, VK_BROWSER_SEARCH }, // 0xE5 VK_PROCESSKEY IME PROCESS key + /* 230 */ { VC_APP_MUSIC, VK_BROWSER_FAVORITES }, // 0xE6 OEM specific + /* 231 */ { VC_UNDEFINED, VK_BROWSER_REFRESH }, // 0xE7 VK_PACKET Used to pass Unicode characters as if they were keystrokes. The VK_PACKET key is the low word of a 32-bit Virtual Key value used for non-keyboard input methods. + /* 232 */ { VC_UNDEFINED, VK_BROWSER_STOP }, // 0xE8 Unassigned + /* 233 */ { VC_UNDEFINED, VK_BROWSER_FORWARD }, // 0xE9 OEM specific + /* 234 */ { VC_UNDEFINED, VK_BROWSER_BACK }, // 0xEA OEM specific + /* 235 */ { VC_UNDEFINED, 0x0000 }, // 0xEB OEM specific + /* 236 */ { VC_UNDEFINED, VK_LAUNCH_APP1 }, // 0xEC OEM specific + /* 237 */ { VC_UNDEFINED, VK_LAUNCH_MEDIA_SELECT }, // 0xED OEM specific + /* 238 */ { VC_UNDEFINED, 0x0000 }, // 0xEE OEM specific + /* 239 */ { VC_UNDEFINED, 0x0000 }, // 0xEF OEM specific + /* 240 */ { VC_UNDEFINED, 0x0000 }, // 0xF0 OEM specific + /* 241 */ { VC_UNDEFINED, 0x0000 }, // 0xF1 OEM specific + /* 242 */ { VC_UNDEFINED, 0x0000 }, // 0xF2 OEM specific + /* 243 */ { VC_UNDEFINED, 0x0000 }, // 0xF3 OEM specific + /* 244 */ { VC_UNDEFINED, 0x0000 }, // 0xF4 OEM specific + /* 245 */ { VC_UNDEFINED, 0x0000 }, // 0xF5 OEM specific + /* 246 */ { VC_UNDEFINED, 0x0000 }, // 0xF6 VK_ATTN Attn key + /* 247 */ { VC_UNDEFINED, 0x0000 }, // 0xF7 VK_CRSEL CrSel key + /* 248 */ { VC_UNDEFINED, 0x0000 }, // 0xF8 VK_EXSEL ExSel key + /* 249 */ { VC_UNDEFINED, 0x0000 }, // 0xF9 VK_EREOF Erase EOF key + /* 250 */ { VC_UNDEFINED, 0x0000 }, // 0xFA VK_PLAY Play key + /* 251 */ { VC_UNDEFINED, 0x0000 }, // 0xFB VK_ZOOM Zoom key + /* 252 */ { VC_UNDEFINED, 0x0000 }, // 0xFC VK_NONAME Reserved + /* 253 */ { VC_UNDEFINED, 0x0000 }, // 0xFD + /* 254 */ { VC_CLEAR, 0x0000 }, // 0xFE VK_OEM_CLEAR Clear key + /* 255 */ { VC_UNDEFINED, 0x0000 } // 0xFE Unassigned +}; + +unsigned short keycode_to_scancode(DWORD vk_code, DWORD flags) { + unsigned short scancode = VC_UNDEFINED; + + // Check the vk_code is in range. + // NOTE vk_code >= 0 is assumed because DWORD is unsigned. + if (vk_code < sizeof(keycode_scancode_table) / sizeof(keycode_scancode_table[0])) { + scancode = keycode_scancode_table[vk_code][0]; + + if (flags & LLKHF_EXTENDED) { + logger(LOG_LEVEL_WARN, "%s [%u]: EXTD2, vk_code %li\n", + __FUNCTION__, __LINE__, vk_code); + + switch (vk_code) { + case VK_PRIOR: + case VK_NEXT: + case VK_END: + case VK_HOME: + case VK_LEFT: + case VK_UP: + case VK_RIGHT: + case VK_DOWN: + + case VK_INSERT: + case VK_DELETE: + scancode |= 0xEE00; + break; + + case VK_RETURN: + scancode |= 0x0E00; + break; + } + } + else { + // logger(LOG_LEVEL_WARN, "%s [%u]: Test2, vk_code %li\n", + // __FUNCTION__, __LINE__, vk_code); + } + } + + return scancode; +} + +DWORD scancode_to_keycode(unsigned short scancode) { + unsigned short keycode = 0x0000; + + // Check the vk_code is in range. + // NOTE vk_code >= 0 is assumed because the scancode is unsigned. + if (scancode < 128) { + keycode = keycode_scancode_table[scancode][1]; + } + else { + // Calculate the upper offset based on the lower half of the scancode + 128. + unsigned short int i = (scancode & 0x007F) | 0x80; + + if (i < sizeof(keycode_scancode_table) / sizeof(keycode_scancode_table[1])) { + keycode = keycode_scancode_table[i][1]; + } + } + + return keycode; +} + + +/************************************************************************/ + +// Structure and pointers for the keyboard locale cache. +typedef struct _KeyboardLocale { + HKL id; // Locale ID + HINSTANCE library; // Keyboard DLL instance. + PVK_TO_BIT pVkToBit; // Pointers struct arrays. + PVK_TO_WCHAR_TABLE pVkToWcharTable; + PDEADKEY pDeadKey; + struct _KeyboardLocale* next; +} KeyboardLocale; + +static KeyboardLocale* locale_first = NULL; +static KeyboardLocale* locale_current = NULL; +static WCHAR deadChar = WCH_NONE; + +// Amount of pointer padding to apply for Wow64 instances. +static unsigned short int ptr_padding = 0; + +#if defined(_WIN32) && !defined(_WIN64) +// Small function to check and see if we are executing under Wow64. +static BOOL is_wow64() { + BOOL status = FALSE; + + LPFN_ISWOW64PROCESS pIsWow64Process = (LPFN_ISWOW64PROCESS) + GetProcAddress(GetModuleHandle("kernel32"), "IsWow64Process"); + + if (pIsWow64Process != NULL) { + HANDLE current_proc = GetCurrentProcess(); + + if (!pIsWow64Process(current_proc, &status)) { + status = FALSE; + + logger(LOG_LEVEL_DEBUG, "%s [%u]: pIsWow64Process(%#p, %#p) failed!\n", + __FUNCTION__, __LINE__, current_proc, &status); + } + } + + return status; +} +#endif + +// Locate the DLL that contains the current keyboard layout. +static int get_keyboard_layout_file(char *layoutFile, DWORD bufferSize) { + int status = IOHOOK_FAILURE; + HKEY hKey; + DWORD varType = REG_SZ; + + char kbdName[KL_NAMELENGTH]; + if (GetKeyboardLayoutName(kbdName)) { + char kbdKeyPath[51 + KL_NAMELENGTH]; + snprintf(kbdKeyPath, 51 + KL_NAMELENGTH, "SYSTEM\\CurrentControlSet\\Control\\Keyboard Layouts\\%s", kbdName); + + if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, (LPCTSTR) kbdKeyPath, 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS) { + if (RegQueryValueEx(hKey, "Layout File", NULL, &varType, (LPBYTE) layoutFile, &bufferSize) == ERROR_SUCCESS) { + RegCloseKey(hKey); + status = IOHOOK_SUCCESS; + } + } + } + + return status; +} + +static int refresh_locale_list() { + int count = 0; + + // Get the number of layouts the user has activated. + int hkl_size = GetKeyboardLayoutList(0, NULL); + if (hkl_size > 0) { + logger(LOG_LEVEL_INFO, "%s [%u]: GetKeyboardLayoutList(0, NULL) found %i layouts.\n", + __FUNCTION__, __LINE__, hkl_size); + + // Get the thread id that currently has focus for our default. + DWORD focus_pid = GetWindowThreadProcessId(GetForegroundWindow(), NULL); + HKL hlk_focus = GetKeyboardLayout(focus_pid); + HKL hlk_default = GetKeyboardLayout(0); + HKL *hkl_list = malloc(sizeof(HKL) * hkl_size); + + int new_size = GetKeyboardLayoutList(hkl_size, hkl_list); + if (new_size > 0) { + if (new_size != hkl_size) { + logger(LOG_LEVEL_WARN, "%s [%u]: Locale size mismatch! " + "Expected %i, received %i!\n", + __FUNCTION__, __LINE__, hkl_size, new_size); + } + else { + logger(LOG_LEVEL_INFO, "%s [%u]: Received %i locales.\n", + __FUNCTION__, __LINE__, new_size); + } + + KeyboardLocale* locale_previous = NULL; + KeyboardLocale* locale_item = locale_first; + + // Go though the linked list and remove KeyboardLocale's that are + // no longer loaded. + while (locale_item != NULL) { + // Check to see if the old HKL is in the new list. + bool is_loaded = false; + int i; + for (i = 0; i < new_size && !is_loaded; i++) { + if (locale_item->id == hkl_list[i]) { + // Flag and jump out of the loop. + hkl_list[i] = NULL; + is_loaded = true; + } + } + + + if (is_loaded) { + logger(LOG_LEVEL_DEBUG, "%s [%u]: Found locale ID %#p in the cache.\n", + __FUNCTION__, __LINE__, locale_item->id); + + // Set the previous local to the current locale. + locale_previous = locale_item; + + // Check and see if the locale is our current active locale. + if (locale_item->id == hlk_focus) { + locale_current = locale_item; + } + + count++; + } + else { + logger(LOG_LEVEL_DEBUG, "%s [%u]: Removing locale ID %#p from the cache.\n", + __FUNCTION__, __LINE__, locale_item->id); + + // If the old id is not in the new list, remove it. + locale_previous->next = locale_item->next; + + // Make sure the locale_current points NULL or something valid. + if (locale_item == locale_current) { + locale_current = NULL; + } + + // Free the memory used by locale_item; + free(locale_item); + + // Set the item to the pervious item to guarantee a next. + locale_item = locale_previous; + } + + // Iterate to the next linked list item. + locale_item = locale_item->next; + } + + + // Insert anything new into the linked list. + int i; + for (i = 0; i < new_size; i++) { + // Check to see if the item was already in the list. + if (hkl_list[i] != NULL) { + // Set the active keyboard layout for this thread to the HKL. + ActivateKeyboardLayout(hkl_list[i], 0x00); + + // Try to pull the current keyboard layout DLL from the registry. + char layoutFile[MAX_PATH]; + if (get_keyboard_layout_file(layoutFile, sizeof(layoutFile)) == IOHOOK_SUCCESS) { + // You can't trust the %SYSPATH%, look it up manually. + char systemDirectory[MAX_PATH]; + if (GetSystemDirectory(systemDirectory, MAX_PATH) != 0) { + char kbdLayoutFilePath[MAX_PATH]; + snprintf(kbdLayoutFilePath, MAX_PATH, "%s\\%s", systemDirectory, layoutFile); + + logger(LOG_LEVEL_DEBUG, "%s [%u]: Loading layout for %#p: %s.\n", + __FUNCTION__, __LINE__, hkl_list[i], layoutFile); + + // Create the new locale item. + locale_item = malloc(sizeof(KeyboardLocale)); + locale_item->id = hkl_list[i]; + locale_item->library = LoadLibrary(kbdLayoutFilePath); + + // Get the function pointer from the library to get the keyboard layer descriptor. + KbdLayerDescriptor pKbdLayerDescriptor = (KbdLayerDescriptor) GetProcAddress(locale_item->library, "KbdLayerDescriptor"); + if (pKbdLayerDescriptor != NULL) { + PKBDTABLES pKbd = pKbdLayerDescriptor(); + + // Store the memory address of the following 3 structures. + BYTE *base = (BYTE *) pKbd; + + // First element of each structure, no offset adjustment needed. + locale_item->pVkToBit = pKbd->pCharModifiers->pVkToBit; + + // Second element of pKbd, +4 byte offset on wow64. + locale_item->pVkToWcharTable = *((PVK_TO_WCHAR_TABLE *) (base + offsetof(KBDTABLES, pVkToWcharTable) + ptr_padding)); + + // Third element of pKbd, +8 byte offset on wow64. + locale_item->pDeadKey = *((PDEADKEY *) (base + offsetof(KBDTABLES, pDeadKey) + (ptr_padding * 2))); + + // This will always be added to the end of the list. + locale_item->next = NULL; + + // Insert the item into the linked list. + if (locale_previous == NULL) { + // If nothing came before, the list is empty. + locale_first = locale_item; + } + else { + // Append the new locale to the end of the list. + locale_previous->next = locale_item; + } + + // Check and see if the locale is our current active locale. + if (locale_item->id == hlk_focus) { + locale_current = locale_item; + } + + // Set the pervious locale item to the new one. + locale_previous = locale_item; + + count++; + } + else { + logger(LOG_LEVEL_ERROR, + "%s [%u]: GetProcAddress() failed for KbdLayerDescriptor!\n", + __FUNCTION__, __LINE__); + + FreeLibrary(locale_item->library); + free(locale_item); + locale_item = NULL; + } + } + else { + logger(LOG_LEVEL_ERROR, + "%s [%u]: GetSystemDirectory() failed!\n", + __FUNCTION__, __LINE__); + } + } + else { + logger(LOG_LEVEL_ERROR, + "%s [%u]: Could not find keyboard map for locale %#p!\n", + __FUNCTION__, __LINE__, hkl_list[i]); + } + } + } + } + else { + logger(LOG_LEVEL_ERROR, + "%s [%u]: GetKeyboardLayoutList() failed!\n", + __FUNCTION__, __LINE__); + + // TODO Try and recover by using the current layout. + // Hint: Use locale_id instead of hkl_list[i] in the loop above. + } + + free(hkl_list); + ActivateKeyboardLayout(hlk_default, 0x00); + } + + return count; +} + +SIZE_T keycode_to_unicode(DWORD keycode, PWCHAR buffer, SIZE_T size) { + // Get the thread id that currently has focus and ask for its current + // locale. + DWORD focus_pid = GetWindowThreadProcessId(GetForegroundWindow(), NULL); + HKL locale_id = GetKeyboardLayout(focus_pid); + + // If the current Locale is not the new locale, search the linked list. + if (locale_current == NULL || locale_current->id != locale_id) { + locale_current = NULL; + KeyboardLocale* locale_item = locale_first; + + // Search the linked list... + while (locale_item != NULL && locale_item->id != locale_id) { + locale_item = locale_item->next; + } + + // You may already be a winner! + if (locale_item != NULL && locale_item->id != locale_id) { + logger(LOG_LEVEL_INFO, + "%s [%u]: Activating keyboard layout %#p.\n", + __FUNCTION__, __LINE__, locale_item->id); + + // Switch the current locale. + locale_current = locale_item; + locale_item = NULL; + + // If they layout changes the dead key state needs to be reset. + // This is consistent with the way Windows handles locale changes. + deadChar = WCH_NONE; + } + else { + logger(LOG_LEVEL_DEBUG, + "%s [%u]: Refreshing locale cache.\n", + __FUNCTION__, __LINE__); + + refresh_locale_list(); + } + } + + // Initialize to empty. + SIZE_T charCount = 0; + // buffer[i] = WCH_NONE; + + // Check and make sure the Unicode helper was loaded. + if (locale_current != NULL) { + logger(LOG_LEVEL_INFO, + "%s [%u]: Using keyboard layout %#p.\n", + __FUNCTION__, __LINE__, locale_current->id); + + int mod = 0; + + int capsLock = (GetKeyState(VK_CAPITAL) & 0x01); + + PVK_TO_BIT pVkToBit = locale_current->pVkToBit; + PVK_TO_WCHAR_TABLE pVkToWcharTable = locale_current->pVkToWcharTable; + PDEADKEY pDeadKey = locale_current->pDeadKey; + + /* Loop over the modifier keys for this locale and determine what is + * currently depressed. Because this is only a structure of two + * bytes, we don't need to worry about the structure padding of __ptr64 + * offsets on Wow64. + */ + bool is_shift = false, is_ctrl = false, is_alt = false; + int i; + for (i = 0; pVkToBit[i].Vk != 0; i++) { + short state = GetAsyncKeyState(pVkToBit[i].Vk); + + // Check to see if the most significant bit is active. + if (state & ~SHRT_MAX) { + if (pVkToBit[i].Vk == VK_SHIFT) { + is_shift = true; + } + else if (pVkToBit[i].Vk == VK_CONTROL) { + is_ctrl = true; + } + else if (pVkToBit[i].Vk == VK_MENU) { + is_alt = true; + } + } + } + + // Check the Shift modifier. + if (is_shift) { + mod = 1; + } + + // Check for the AltGr modifier. + if (is_ctrl && is_alt) { + mod += 3; + } + + // Default 32 bit structure size should be 6 bytes (4 for the pointer and 2 + // additional byte fields) that are padded out to 8 bytes by the compiler. + unsigned short sizeVkToWcharTable = sizeof(VK_TO_WCHAR_TABLE); + #if defined(_WIN32) && !defined(_WIN64) + if (is_wow64()) { + // If we are running under Wow64 the size of the first pointer will be + // 8 bringing the total size to 10 bytes padded out to 16. + sizeVkToWcharTable = (sizeVkToWcharTable + ptr_padding + 7) & -8; + } + #endif + + BYTE *ptrCurrentVkToWcharTable = (BYTE *) pVkToWcharTable; + + int cbSize, n; + do { + // cbSize is used to calculate n, and n is used for the size of pVkToWchars[j].wch[n] + cbSize = *(ptrCurrentVkToWcharTable + offsetof(VK_TO_WCHAR_TABLE, cbSize) + ptr_padding); + n = (cbSize - 2) / 2; + + // Same as VK_TO_WCHARS pVkToWchars[] = pVkToWcharTable[i].pVkToWchars + PVK_TO_WCHARS pVkToWchars = (PVK_TO_WCHARS) ((PVK_TO_WCHAR_TABLE) ptrCurrentVkToWcharTable)->pVkToWchars; + + if (pVkToWchars != NULL && mod < n) { + // pVkToWchars[j].VirtualKey + BYTE *pCurrentVkToWchars = (BYTE *) pVkToWchars; + + do { + if (((PVK_TO_WCHARS) pCurrentVkToWchars)->VirtualKey == keycode) { + if ((((PVK_TO_WCHARS) pCurrentVkToWchars)->Attributes == CAPLOK) && capsLock) { + if (is_shift && mod > 0) { + mod -= 1; + } + else { + mod += 1; + } + } + + // Set the initial unicode char. + WCHAR unicode = ((PVK_TO_WCHARS) pCurrentVkToWchars)->wch[mod]; + + // Increment the pCurrentVkToWchars by the size of wch[n]. + pCurrentVkToWchars += sizeof(VK_TO_WCHARS) + (sizeof(WCHAR) * n); + + + if (unicode == WCH_DEAD) { + // The current unicode char is a dead key... + if (deadChar == WCH_NONE) { + // No previous dead key was set so cache the next + // wchar so we know what to do next time its pressed. + deadChar = ((PVK_TO_WCHARS) pCurrentVkToWchars)->wch[mod]; + } + else { + if (size >= 2) { + // Received a second dead key. + memset(buffer, deadChar, 2); + //buffer[0] = deadChar; + //buffer[1] = deadChar; + + deadChar = WCH_NONE; + charCount = 2; + } + } + } + else if (unicode != WCH_NONE) { + // We are not WCH_NONE or WCH_DEAD + if (size >= 1) { + buffer[0] = unicode; + charCount = 1; + } + } + + break; + } + else { + // Add sizeof WCHAR because we are really an array of WCHAR[n] not WCHAR[] + pCurrentVkToWchars += sizeof(VK_TO_WCHARS) + (sizeof(WCHAR) * n); + } + } while ( ((PVK_TO_WCHARS) pCurrentVkToWchars)->VirtualKey != 0 ); + } + + // This is effectively the same as: ptrCurrentVkToWcharTable = pVkToWcharTable[++i]; + ptrCurrentVkToWcharTable += sizeVkToWcharTable; + } while (cbSize != 0); + + + // If the current local has a dead key set. + if (deadChar != WCH_NONE) { + // Loop over the pDeadKey lookup table for the locale. + int i; + for (i = 0; pDeadKey[i].dwBoth != 0; i++) { + WCHAR baseChar = (WCHAR) pDeadKey[i].dwBoth; + WCHAR diacritic = (WCHAR) (pDeadKey[i].dwBoth >> 16); + + // If we locate an extended dead char, set it. + if (size >= 1 && baseChar == buffer[0] && diacritic == deadChar) { + deadChar = WCH_NONE; + + if (charCount <= size) { + memset(buffer, (WCHAR) pDeadKey[i].wchComposed, charCount); + //buffer[i] = (WCHAR) pDeadKey[i].wchComposed; + } + } + } + } + } + + return charCount; +} + +int load_input_helper() { + int count = 0; + + #if defined(_WIN32) && !defined(_WIN64) + if (is_wow64()) { + ptr_padding = sizeof(void *); + } + #endif + + count = refresh_locale_list(); + + logger(LOG_LEVEL_INFO, + "%s [%u]: refresh_locale_list() found %i locale(s).\n", + __FUNCTION__, __LINE__, count); + + return count; +} + +// This returns the number of locales that were removed. +int unload_input_helper() { + int count = 0; + + // Cleanup and free memory from the old list. + KeyboardLocale* locale_item = locale_first; + while (locale_item != NULL) { + // Remove the first item from the linked list. + FreeLibrary(locale_item->library); + locale_first = locale_item->next; + free(locale_item); + locale_item = locale_first; + + count++; + } + + // Reset the current local. + locale_current = NULL; + + return count; +} diff --git a/vendor/github.com/robotn/gohook/hook/windows/properties_c.h b/vendor/github.com/robotn/gohook/hook/windows/properties_c.h new file mode 100644 index 0000000..3c8ea2b --- /dev/null +++ b/vendor/github.com/robotn/gohook/hook/windows/properties_c.h @@ -0,0 +1,211 @@ + +#ifdef HAVE_CONFIG_H + #include +#endif + +#include +#include "../iohook.h" +#include "input.h" +// #include "logger.h" + +// The handle to the DLL module pulled in DllMain on DLL_PROCESS_ATTACH. +HINSTANCE hInst; + +// input_hook.c +extern void unregister_running_hooks(); + + +// Structure for the monitor_enum_proc() callback so we can track the count. +typedef struct _screen_info { + uint8_t count; + screen_data *data; +} screen_info; + + +static BOOL CALLBACK monitor_enum_proc(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData) { + int width = lprcMonitor->right - lprcMonitor->left; + int height = lprcMonitor->bottom - lprcMonitor->top; + int origin_x = lprcMonitor->left; + int origin_y = lprcMonitor->top; + + if (width > 0 && height > 0) { + screen_info *screens = (screen_info *) dwData; + + if (screens->data == NULL) { + screens->data = (screen_data *) malloc(sizeof(screen_data)); + } + else { + screens->data = (screen_data *) realloc(screens, sizeof(screen_data) * screens->count); + } + + screens->data[screens->count++] = (screen_data) { + // Should monitor count start @ zero? Currently it starts at 1. + .number = screens->count, + .x = origin_x, + .y = origin_y, + .width = width, + .height = height + }; + + logger(LOG_LEVEL_INFO, "%s [%u]: Monitor %d: %ldx%ld (%ld, %ld)\n", + __FUNCTION__, __LINE__, screens->count, width, height, origin_x, origin_y); + } + + return TRUE; +} + +IOHOOK_API screen_data* hook_create_screen_info(unsigned char *count) { + // Initialize count to zero. + *count = 0; + + // Create a simple structure to make working with monitor_enum_proc easier. + screen_info screens = { + .count = 0, + .data = NULL + }; + + BOOL status = EnumDisplayMonitors(NULL, NULL, monitor_enum_proc, (LPARAM) &screens); + + if (!status || screens.count == 0) { + // Fallback in case EnumDisplayMonitors fails. + logger(LOG_LEVEL_INFO, "%s [%u]: EnumDisplayMonitors failed. Fallback.\n", + __FUNCTION__, __LINE__); + + int width = GetSystemMetrics(SM_CXSCREEN); + int height = GetSystemMetrics(SM_CYSCREEN); + + if (width > 0 && height > 0) { + screens.data = (screen_data *) malloc(sizeof(screen_data)); + + if (screens.data != NULL) { + *count = 1; + screens.data[0] = (screen_data) { + .number = 1, + .x = 0, + .y = 0, + .width = width, + .height = height + }; + } + } + } else { + // Populate the count. + *count = screens.count; + } + + return screens.data; +} + +IOHOOK_API long int hook_get_auto_repeat_rate() { + long int value = -1; + long int rate; + + if (SystemParametersInfo(SPI_GETKEYBOARDSPEED, 0, &rate, 0)) { + logger(LOG_LEVEL_INFO, "%s [%u]: SPI_GETKEYBOARDSPEED: %li.\n", + __FUNCTION__, __LINE__, rate); + + value = rate; + } + + return value; +} + +IOHOOK_API long int hook_get_auto_repeat_delay() { + long int value = -1; + long int delay; + + if (SystemParametersInfo(SPI_GETKEYBOARDDELAY, 0, &delay, 0)) { + logger(LOG_LEVEL_INFO, "%s [%u]: SPI_GETKEYBOARDDELAY: %li.\n", + __FUNCTION__, __LINE__, delay); + + value = delay; + } + + return value; +} + +IOHOOK_API long int hook_get_pointer_acceleration_multiplier() { + long int value = -1; + int mouse[3]; // 0-Threshold X, 1-Threshold Y and 2-Speed. + + if (SystemParametersInfo(SPI_GETMOUSE, 0, &mouse, 0)) { + logger(LOG_LEVEL_INFO, "%s [%u]: SPI_GETMOUSE[2]: %i.\n", + __FUNCTION__, __LINE__, mouse[2]); + + value = mouse[2]; + } + + return value; +} + +IOHOOK_API long int hook_get_pointer_acceleration_threshold() { + long int value = -1; + int mouse[3]; // 0-Threshold X, 1-Threshold Y and 2-Speed. + + if (SystemParametersInfo(SPI_GETMOUSE, 0, &mouse, 0)) { + logger(LOG_LEVEL_INFO, "%s [%u]: SPI_GETMOUSE[0]: %i.\n", + __FUNCTION__, __LINE__, mouse[0]); + logger(LOG_LEVEL_INFO, "%s [%u]: SPI_GETMOUSE[1]: %i.\n", + __FUNCTION__, __LINE__, mouse[1]); + + // Average the x and y thresholds. + value = (mouse[0] + mouse[1]) / 2; + } + + return value; +} + +IOHOOK_API long int hook_get_pointer_sensitivity() { + long int value = -1; + int sensitivity; + + if (SystemParametersInfo(SPI_GETMOUSESPEED, 0, &sensitivity, 0)) { + logger(LOG_LEVEL_INFO, "%s [%u]: SPI_GETMOUSESPEED: %i.\n", + __FUNCTION__, __LINE__, sensitivity); + + value = sensitivity; + } + + return value; +} + +IOHOOK_API long int hook_get_multi_click_time() { + long int value = -1; + UINT clicktime; + + clicktime = GetDoubleClickTime(); + logger(LOG_LEVEL_INFO, "%s [%u]: GetDoubleClickTime: %u.\n", + __FUNCTION__, __LINE__, (unsigned int) clicktime); + + value = (long int) clicktime; + + return value; +} + +// DLL Entry point. +BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpReserved) { + switch (fdwReason) { + case DLL_PROCESS_ATTACH: + // Save the DLL address. + hInst = hInstDLL; + + // Initialize native input helper functions. + load_input_helper(); + break; + + case DLL_PROCESS_DETACH: + // Unregister any hooks that may still be installed. + unregister_running_hooks(); + + // Deinitialize native input helper functions. + unload_input_helper(); + break; + + case DLL_THREAD_ATTACH: + case DLL_THREAD_DETACH: + // Do Nothing. + break; + } + + return TRUE; +} diff --git a/vendor/github.com/robotn/gohook/hook/x11/event_c.h b/vendor/github.com/robotn/gohook/hook/x11/event_c.h new file mode 100644 index 0000000..50e5ede --- /dev/null +++ b/vendor/github.com/robotn/gohook/hook/x11/event_c.h @@ -0,0 +1,386 @@ + +#ifdef HAVE_CONFIG_H + #include +#endif + +#include +#include +#include +#include +#include +#ifdef USE_XTEST + #include +#endif + +#include "../iohook.h" +#include "input.h" +// #include "../logger.h" + +extern Display *properties_disp; + +// This lookup table must be in the same order the masks are defined. +#ifdef USE_XTEST +static KeySym keymask_lookup[8] = { + XK_Shift_L, + XK_Control_L, + XK_Meta_L, + XK_Alt_L, + + XK_Shift_R, + XK_Control_R, + XK_Meta_R, + XK_Alt_R +}; + +static unsigned int btnmask_lookup[5] = { + MASK_BUTTON1, + MASK_BUTTON2, + MASK_BUTTON3, + MASK_BUTTON4, + MASK_BUTTON5 +}; +#else +// TODO Possibly relocate to input helper. +static unsigned int convert_to_native_mask(unsigned int mask) { + unsigned int native_mask = 0x00; + + if (mask & (MASK_SHIFT)) { native_mask |= ShiftMask; } + if (mask & (MASK_CTRL)) { native_mask |= ControlMask; } + if (mask & (MASK_META)) { native_mask |= Mod4Mask; } + if (mask & (MASK_ALT)) { native_mask |= Mod1Mask; } + + if (mask & MASK_BUTTON1) { native_mask |= Button1Mask; } + if (mask & MASK_BUTTON2) { native_mask |= Button2Mask; } + if (mask & MASK_BUTTON3) { native_mask |= Button3Mask; } + if (mask & MASK_BUTTON4) { native_mask |= Button4Mask; } + if (mask & MASK_BUTTON5) { native_mask |= Button5Mask; } + + return native_mask; +} +#endif + +static inline void post_key_event(iohook_event * const event) { + #ifdef USE_XTEST + // FIXME Currently ignoring EVENT_KEY_TYPED. + if (event->type == EVENT_KEY_PRESSED) { + XTestFakeKeyEvent( + properties_disp, + scancode_to_keycode(event->data.keyboard.keycode), + True, + 0); + } + else if (event->type == EVENT_KEY_RELEASED) { + XTestFakeKeyEvent( + properties_disp, + scancode_to_keycode(event->data.keyboard.keycode), + False, + 0); + } + #else + XKeyEvent key_event; + + key_event.serial = 0x00; + key_event.send_event = False; + key_event.display = properties_disp; + key_event.time = CurrentTime; + key_event.same_screen = True; + + unsigned int mask; + if (!XQueryPointer(properties_disp, DefaultRootWindow(properties_disp), &(key_event.root), &(key_event.subwindow), &(key_event.x_root), &(key_event.y_root), &(key_event.x), &(key_event.y), &mask)) { + key_event.root = DefaultRootWindow(properties_disp); + key_event.window = key_event.root; + key_event.subwindow = None; + + key_event.x_root = 0; + key_event.y_root = 0; + key_event.x = 0; + key_event.y = 0; + } + + key_event.state = convert_to_native_mask(event->mask); + key_event.keycode = XKeysymToKeycode(properties_disp, scancode_to_keycode(event->data.keyboard.keycode)); + + // FIXME Currently ignoring typed events. + if (event->type == EVENT_KEY_PRESSED) { + key_event.type = KeyPress; + XSendEvent(properties_disp, InputFocus, False, KeyPressMask, (XEvent *) &key_event); + } + else if (event->type == EVENT_KEY_RELEASED) { + key_event.type = KeyRelease; + XSendEvent(properties_disp, InputFocus, False, KeyReleaseMask, (XEvent *) &key_event); + } + #endif +} + +static inline void post_mouse_button_event(iohook_event * const event) { + #ifdef USE_XTEST + Window ret_root; + Window ret_child; + int root_x; + int root_y; + int win_x; + int win_y; + unsigned int mask; + + Window win_root = XDefaultRootWindow(properties_disp); + Bool query_status = XQueryPointer(properties_disp, win_root, &ret_root, &ret_child, &root_x, &root_y, &win_x, &win_y, &mask); + if (query_status) { + if (event->data.mouse.x != root_x || event->data.mouse.y != root_y) { + // Move the pointer to the specified position. + XTestFakeMotionEvent(properties_disp, -1, event->data.mouse.x, event->data.mouse.y, 0); + } + else { + query_status = False; + } + } + + if (event->type == EVENT_MOUSE_WHEEL) { + // Wheel events should be the same as click events on X11. + // type, amount and rotation + if (event->data.wheel.rotation < 0) { + XTestFakeButtonEvent(properties_disp, WheelUp, True, 0); + XTestFakeButtonEvent(properties_disp, WheelUp, False, 0); + } + else { + XTestFakeButtonEvent(properties_disp, WheelDown, True, 0); + XTestFakeButtonEvent(properties_disp, WheelDown, False, 0); + } + } + else if (event->type == EVENT_MOUSE_PRESSED) { + XTestFakeButtonEvent(properties_disp, event->data.mouse.button, True, 0); + } + else if (event->type == EVENT_MOUSE_RELEASED) { + XTestFakeButtonEvent(properties_disp, event->data.mouse.button, False, 0); + } + else if (event->type == EVENT_MOUSE_CLICKED) { + XTestFakeButtonEvent(properties_disp, event->data.mouse.button, True, 0); + XTestFakeButtonEvent(properties_disp, event->data.mouse.button, False, 0); + } + + if (query_status) { + // Move the pointer back to the original position. + XTestFakeMotionEvent(properties_disp, -1, root_x, root_y, 0); + } + #else + XButtonEvent btn_event; + + btn_event.serial = 0x00; + btn_event.send_event = False; + btn_event.display = properties_disp; + btn_event.time = CurrentTime; + btn_event.same_screen = True; + + btn_event.root = DefaultRootWindow(properties_disp); + btn_event.window = btn_event.root; + btn_event.subwindow = None; + + btn_event.type = 0x00; + btn_event.state = 0x00; + btn_event.x_root = 0; + btn_event.y_root = 0; + btn_event.x = 0; + btn_event.y = 0; + btn_event.button = 0x00; + + btn_event.state = convert_to_native_mask(event->mask); + + btn_event.x = event->data.mouse.x; + btn_event.y = event->data.mouse.y; + + #if defined(USE_XINERAMA) || defined(USE_XRANDR) + uint8_t screen_count; + screen_data *screens = hook_create_screen_info(&screen_count); + if (screen_count > 1) { + btn_event.x += screens[0].x; + btn_event.y += screens[0].y; + } + + if (screens != NULL) { + free(screens); + } + #endif + + // These are the same because Window == Root Window. + btn_event.x_root = btn_event.x; + btn_event.y_root = btn_event.y; + + if (event->type == EVENT_MOUSE_WHEEL) { + // type, amount and rotation + if (event->data.wheel.rotation < 0) { + btn_event.button = WheelUp; + } + else { + btn_event.button = WheelDown; + } + } + + if (event->type != EVENT_MOUSE_RELEASED) { + // FIXME Where do we set event->button? + btn_event.type = ButtonPress; + XSendEvent(properties_disp, InputFocus, False, ButtonPressMask, (XEvent *) &btn_event); + } + + if (event->type != EVENT_MOUSE_PRESSED) { + btn_event.type = ButtonRelease; + XSendEvent(properties_disp, InputFocus, False, ButtonReleaseMask, (XEvent *) &btn_event); + } + #endif +} + +static inline void post_mouse_motion_event(iohook_event * const event) { + #ifdef USE_XTEST + XTestFakeMotionEvent(properties_disp, -1, event->data.mouse.x, event->data.mouse.y, 0); + #else + XMotionEvent mov_event; + + mov_event.serial = MotionNotify; + mov_event.send_event = False; + mov_event.display = properties_disp; + mov_event.time = CurrentTime; + mov_event.same_screen = True; + mov_event.is_hint = NotifyNormal, + mov_event.root = DefaultRootWindow(properties_disp); + mov_event.window = mov_event.root; + mov_event.subwindow = None; + + mov_event.type = 0x00; + mov_event.state = 0x00; + mov_event.x_root = 0; + mov_event.y_root = 0; + mov_event.x = 0; + mov_event.y = 0; + + mov_event.state = convert_to_native_mask(event->mask); + + mov_event.x = event->data.mouse.x; + mov_event.y = event->data.mouse.y; + + #if defined(USE_XINERAMA) || defined(USE_XRANDR) + uint8_t screen_count; + screen_data *screens = hook_create_screen_info(&screen_count); + if (screen_count > 1) { + mov_event.x += screens[0].x; + mov_event.y += screens[0].y; + } + + if (screens != NULL) { + free(screens); + } + #endif + + // These are the same because Window == Root Window. + mov_event.x_root = mov_event.x; + mov_event.y_root = mov_event.y; + + long int event_mask = NoEventMask; + if (event->type == EVENT_MOUSE_DRAGGED) { + #if Button1Mask == Button1MotionMask && \ + Button2Mask == Button2MotionMask && \ + Button3Mask == Button3MotionMask && \ + Button4Mask == Button4MotionMask && \ + Button5Mask == Button5MotionMask + // This little trick only works if Button#MotionMasks align with + // the Button#Masks. + event_mask = mov_event.state & + (Button1MotionMask | Button2MotionMask | + Button2MotionMask | Button3MotionMask | Button5MotionMask); + #else + // Fallback to some slightly larger... + if (event->state & Button1Mask) { + event_mask |= Button1MotionMask; + } + + if (event->state & Button2Mask) { + event_mask |= Button2MotionMask; + } + + if (event->state & Button3Mask) { + event_mask |= Button3MotionMask; + } + + if (event->state & Button4Mask) { + event_mask |= Button4MotionMask; + } + + if (event->state & Button5Mask) { + event_mask |= Button5MotionMask; + } + #endif + } + + // NOTE x_mask = NoEventMask. + XSendEvent(properties_disp, InputFocus, False, event_mask, (XEvent *) &mov_event); + #endif +} + +IOHOOK_API void hook_post_event(iohook_event * const event) { + XLockDisplay(properties_disp); + + #ifdef USE_XTEST + // XTest does not have modifier support, so we fake it by depressing the + // appropriate modifier keys. + unsigned int i; + for (i = 0; i < sizeof(keymask_lookup) / sizeof(KeySym); i++) { + if (event->mask & 1 << i) { + XTestFakeKeyEvent(properties_disp, XKeysymToKeycode(properties_disp, keymask_lookup[i]), True, 0); + } + } + + unsigned int i; + for (i = 0; i < sizeof(btnmask_lookup) / sizeof(unsigned int); i++) { + if (event->mask & btnmask_lookup[i]) { + XTestFakeButtonEvent(properties_disp, i + 1, True, 0); + } + } + #endif + + switch (event->type) { + case EVENT_KEY_PRESSED: + case EVENT_KEY_RELEASED: + case EVENT_KEY_TYPED: + post_key_event(event); + break; + + case EVENT_MOUSE_PRESSED: + case EVENT_MOUSE_RELEASED: + case EVENT_MOUSE_WHEEL: + case EVENT_MOUSE_CLICKED: + post_mouse_button_event(event); + break; + + case EVENT_MOUSE_DRAGGED: + case EVENT_MOUSE_MOVED: + post_mouse_motion_event(event); + break; + + case EVENT_HOOK_ENABLED: + case EVENT_HOOK_DISABLED: + // Ignore hook enabled / disabled events. + + default: + // Ignore any other garbage. + logger(LOG_LEVEL_WARN, "%s [%u]: Ignoring post event type %#X\n", + __FUNCTION__, __LINE__, event->type); + break; + } + + #ifdef USE_XTEST + // Release the previously held modifier keys used to fake the event mask. + unsigned int i ; + for (i= 0; i < sizeof(keymask_lookup) / sizeof(KeySym); i++) { + if (event->mask & 1 << i) { + XTestFakeKeyEvent(properties_disp, XKeysymToKeycode(properties_disp, keymask_lookup[i]), False, 0); + } + } + unsigned int i; + for (i = 0; i < sizeof(btnmask_lookup) / sizeof(unsigned int); i++) { + if (event->mask & btnmask_lookup[i]) { + XTestFakeButtonEvent(properties_disp, i + 1, False, 0); + } + } + #endif + + // Don't forget to flush! + XSync(properties_disp, True); + XUnlockDisplay(properties_disp); +} diff --git a/vendor/github.com/robotn/gohook/hook/x11/hook_c.h b/vendor/github.com/robotn/gohook/hook/x11/hook_c.h new file mode 100644 index 0000000..4be4b60 --- /dev/null +++ b/vendor/github.com/robotn/gohook/hook/x11/hook_c.h @@ -0,0 +1,1132 @@ + +#ifdef HAVE_CONFIG_H + #include +#endif + +#define USE_XKB 0 +#define USE_XKBCOMMON 0 +#include +#include +#ifdef USE_XRECORD_ASYNC + #include +#endif +#include + +#include +#include +#include +#include +// #ifdef USE_XKB +#include +#include +// #endif +#if defined(USE_XINERAMA) && !defined(USE_XRANDR) + #include +#elif defined(USE_XRANDR) + #include +#else +// TODO We may need to fallback to the xf86vm extension for things like TwinView. +// #pragma message("*** Warning: Xinerama or XRandR support is required to produce cross-platform mouse coordinates for multi-head configurations!") +// #pragma message("... Assuming single-head display.") +#endif + +#include "../iohook.h" +// #include "../logger.h" +#include "input.h" + +// Thread and hook handles. +#ifdef USE_XRECORD_ASYNC +static bool running; + +static pthread_cond_t hook_xrecord_cond = PTHREAD_COND_INITIALIZER; +static pthread_mutex_t hook_xrecord_mutex = PTHREAD_MUTEX_INITIALIZER; +#endif + +typedef struct _hook_info { + struct _data { + Display *display; + XRecordRange *range; + } data; + struct _ctrl { + Display *display; + XRecordContext context; + } ctrl; + struct _input { + #ifdef USE_XKBCOMMON + xcb_connection_t *connection; + struct xkb_context *context; + #endif + uint16_t mask; + struct _mouse { + bool is_dragged; + struct _click { + unsigned short int count; + long int time; + unsigned short int button; + } click; + } mouse; + } input; +} hook_info; +static hook_info *hook; + +// For this struct, refer to libxnee, requires Xlibint.h +typedef union { + unsigned char type; + xEvent event; + xResourceReq req; + xGenericReply reply; + xError error; + xConnSetupPrefix setup; +} XRecordDatum; + +#if defined(USE_XKBCOMMON) +//struct xkb_keymap *keymap; +//struct xkb_state *state = xkb_state_new(keymap); +static struct xkb_state *state = NULL; +#endif + +// Virtual event pointer. +static iohook_event event; + +// Event dispatch callback. +static dispatcher_t dispatcher = NULL; + +IOHOOK_API void hook_set_dispatch_proc(dispatcher_t dispatch_proc) { + logger(LOG_LEVEL_DEBUG, "%s [%u]: Setting new dispatch callback to %#p.\n", + __FUNCTION__, __LINE__, dispatch_proc); + + dispatcher = dispatch_proc; +} + +// Send out an event if a dispatcher was set. +static inline void dispatch_event(iohook_event *const event) { + if (dispatcher != NULL) { + logger(LOG_LEVEL_DEBUG, "%s [%u]: Dispatching event type %u.\n", + __FUNCTION__, __LINE__, event->type); + + dispatcher(event); + } + else { + logger(LOG_LEVEL_WARN, "%s [%u]: No dispatch callback set!\n", + __FUNCTION__, __LINE__); + } +} + +// Set the native modifier mask for future events. +static inline void set_modifier_mask(uint16_t mask) { + hook->input.mask |= mask; +} + +// Unset the native modifier mask for future events. +static inline void unset_modifier_mask(uint16_t mask) { + hook->input.mask &= ~mask; +} + +// Get the current native modifier mask state. +static inline uint16_t get_modifiers() { + return hook->input.mask; +} + +// Initialize the modifier lock masks. +static void initialize_locks() { + #ifdef USE_XKBCOMMON + + if (xkb_state_led_name_is_active(state, XKB_LED_NAME_CAPS)) { + set_modifier_mask(MASK_CAPS_LOCK); + } + else { + unset_modifier_mask(MASK_CAPS_LOCK); + } + + if (xkb_state_led_name_is_active(state, XKB_LED_NAME_NUM)) { + set_modifier_mask(MASK_NUM_LOCK); + } + else { + unset_modifier_mask(MASK_NUM_LOCK); + } + + if (xkb_state_led_name_is_active(state, XKB_LED_NAME_SCROLL)) { + set_modifier_mask(MASK_SCROLL_LOCK); + } + else { + unset_modifier_mask(MASK_SCROLL_LOCK); + } + #else + unsigned int led_mask = 0x00; + if (XkbGetIndicatorState(hook->ctrl.display, XkbUseCoreKbd, &led_mask) == Success) { + if (led_mask & 0x01) { + set_modifier_mask(MASK_CAPS_LOCK); + } + else { + unset_modifier_mask(MASK_CAPS_LOCK); + } + + if (led_mask & 0x02) { + set_modifier_mask(MASK_NUM_LOCK); + } + else { + unset_modifier_mask(MASK_NUM_LOCK); + } + + if (led_mask & 0x04) { + set_modifier_mask(MASK_SCROLL_LOCK); + } + else { + unset_modifier_mask(MASK_SCROLL_LOCK); + } + } + else { + logger(LOG_LEVEL_WARN, "%s [%u]: XkbGetIndicatorState failed to get current led mask!\n", + __FUNCTION__, __LINE__); + } + #endif +} + +// Initialize the modifier mask to the current modifiers. +static void initialize_modifiers() { + hook->input.mask = 0x0000; + + KeyCode keycode; + char keymap[32]; + XQueryKeymap(hook->ctrl.display, keymap); + + Window unused_win; + int unused_int; + unsigned int mask; + if (XQueryPointer(hook->ctrl.display, DefaultRootWindow(hook->ctrl.display), &unused_win, &unused_win, &unused_int, &unused_int, &unused_int, &unused_int, &mask)) { + if (mask & ShiftMask) { + keycode = XKeysymToKeycode(hook->ctrl.display, XK_Shift_L); + if (keymap[keycode / 8] & (1 << (keycode % 8))) { set_modifier_mask(MASK_SHIFT_L); } + keycode = XKeysymToKeycode(hook->ctrl.display, XK_Shift_R); + if (keymap[keycode / 8] & (1 << (keycode % 8))) { set_modifier_mask(MASK_SHIFT_R); } + } + if (mask & ControlMask) { + keycode = XKeysymToKeycode(hook->ctrl.display, XK_Control_L); + if (keymap[keycode / 8] & (1 << (keycode % 8))) { set_modifier_mask(MASK_CTRL_L); } + keycode = XKeysymToKeycode(hook->ctrl.display, XK_Control_R); + if (keymap[keycode / 8] & (1 << (keycode % 8))) { set_modifier_mask(MASK_CTRL_R); } + } + if (mask & Mod1Mask) { + keycode = XKeysymToKeycode(hook->ctrl.display, XK_Alt_L); + if (keymap[keycode / 8] & (1 << (keycode % 8))) { set_modifier_mask(MASK_ALT_L); } + keycode = XKeysymToKeycode(hook->ctrl.display, XK_Alt_R); + if (keymap[keycode / 8] & (1 << (keycode % 8))) { set_modifier_mask(MASK_ALT_R); } + } + if (mask & Mod4Mask) { + keycode = XKeysymToKeycode(hook->ctrl.display, XK_Super_L); + if (keymap[keycode / 8] & (1 << (keycode % 8))) { set_modifier_mask(MASK_META_L); } + keycode = XKeysymToKeycode(hook->ctrl.display, XK_Super_R); + if (keymap[keycode / 8] & (1 << (keycode % 8))) { set_modifier_mask(MASK_META_R); } + } + + if (mask & Button1Mask) { set_modifier_mask(MASK_BUTTON1); } + if (mask & Button2Mask) { set_modifier_mask(MASK_BUTTON2); } + if (mask & Button3Mask) { set_modifier_mask(MASK_BUTTON3); } + if (mask & Button4Mask) { set_modifier_mask(MASK_BUTTON4); } + if (mask & Button5Mask) { set_modifier_mask(MASK_BUTTON5); } + } + else { + logger(LOG_LEVEL_WARN, "%s [%u]: XQueryPointer failed to get current modifiers!\n", + __FUNCTION__, __LINE__); + + keycode = XKeysymToKeycode(hook->ctrl.display, XK_Shift_L); + if (keymap[keycode / 8] & (1 << (keycode % 8))) { set_modifier_mask(MASK_SHIFT_L); } + keycode = XKeysymToKeycode(hook->ctrl.display, XK_Shift_R); + if (keymap[keycode / 8] & (1 << (keycode % 8))) { set_modifier_mask(MASK_SHIFT_R); } + keycode = XKeysymToKeycode(hook->ctrl.display, XK_Control_L); + if (keymap[keycode / 8] & (1 << (keycode % 8))) { set_modifier_mask(MASK_CTRL_L); } + keycode = XKeysymToKeycode(hook->ctrl.display, XK_Control_R); + if (keymap[keycode / 8] & (1 << (keycode % 8))) { set_modifier_mask(MASK_CTRL_R); } + keycode = XKeysymToKeycode(hook->ctrl.display, XK_Alt_L); + if (keymap[keycode / 8] & (1 << (keycode % 8))) { set_modifier_mask(MASK_ALT_L); } + keycode = XKeysymToKeycode(hook->ctrl.display, XK_Alt_R); + if (keymap[keycode / 8] & (1 << (keycode % 8))) { set_modifier_mask(MASK_ALT_R); } + keycode = XKeysymToKeycode(hook->ctrl.display, XK_Super_L); + if (keymap[keycode / 8] & (1 << (keycode % 8))) { set_modifier_mask(MASK_META_L); } + keycode = XKeysymToKeycode(hook->ctrl.display, XK_Super_R); + if (keymap[keycode / 8] & (1 << (keycode % 8))) { set_modifier_mask(MASK_META_R); } + } + + initialize_locks(); +} + +void hook_event_proc(XPointer closeure, XRecordInterceptData *recorded_data) { + uint64_t timestamp = (uint64_t) recorded_data->server_time; + + if (recorded_data->category == XRecordStartOfData) { + // Populate the hook start event. + event.time = timestamp; + event.reserved = 0x00; + + event.type = EVENT_HOOK_ENABLED; + event.mask = 0x00; + + // Fire the hook start event. + dispatch_event(&event); + } + else if (recorded_data->category == XRecordEndOfData) { + // Populate the hook stop event. + event.time = timestamp; + event.reserved = 0x00; + + event.type = EVENT_HOOK_DISABLED; + event.mask = 0x00; + + // Fire the hook stop event. + dispatch_event(&event); + } + else if (recorded_data->category == XRecordFromServer || recorded_data->category == XRecordFromClient) { + // Get XRecord data. + XRecordDatum *data = (XRecordDatum *) recorded_data->data; + + if (data->type == KeyPress) { + // The X11 KeyCode associated with this event. + KeyCode keycode = (KeyCode) data->event.u.u.detail; + KeySym keysym = 0x00; + #if defined(USE_XKBCOMMON) + if (state != NULL) { + keysym = xkb_state_key_get_one_sym(state, keycode); + } + #else + keysym = keycode_to_keysym(keycode, data->event.u.keyButtonPointer.state); + #endif + + unsigned short int scancode = keycode_to_scancode(keycode); + + // TODO If you have a better suggestion for this ugly, let me know. + if (scancode == VC_SHIFT_L) { set_modifier_mask(MASK_SHIFT_L); } + else if (scancode == VC_SHIFT_R) { set_modifier_mask(MASK_SHIFT_R); } + else if (scancode == VC_CONTROL_L) { set_modifier_mask(MASK_CTRL_L); } + else if (scancode == VC_CONTROL_R) { set_modifier_mask(MASK_CTRL_R); } + else if (scancode == VC_ALT_L) { set_modifier_mask(MASK_ALT_L); } + else if (scancode == VC_ALT_R) { set_modifier_mask(MASK_ALT_R); } + else if (scancode == VC_META_L) { set_modifier_mask(MASK_META_L); } + else if (scancode == VC_META_R) { set_modifier_mask(MASK_META_R); } + xkb_state_update_key(state, keycode, XKB_KEY_DOWN); + initialize_locks(); + + if ((get_modifiers() & MASK_NUM_LOCK) == 0) { + switch (scancode) { + case VC_KP_SEPARATOR: + case VC_KP_1: + case VC_KP_2: + case VC_KP_3: + case VC_KP_4: + case VC_KP_5: + case VC_KP_6: + case VC_KP_7: + case VC_KP_8: + case VC_KP_0: + case VC_KP_9: + scancode |= 0xEE00; + break; + } + } + + // Populate key pressed event. + event.time = timestamp; + event.reserved = 0x00; + + event.type = EVENT_KEY_PRESSED; + event.mask = get_modifiers(); + + event.data.keyboard.keycode = scancode; + event.data.keyboard.rawcode = keysym; + event.data.keyboard.keychar = CHAR_UNDEFINED; + + logger(LOG_LEVEL_INFO, "%s [%u]: Key %#X pressed. (%#X)\n", + __FUNCTION__, __LINE__, event.data.keyboard.keycode, event.data.keyboard.rawcode); + + // Fire key pressed event. + dispatch_event(&event); + + // If the pressed event was not consumed... + if (event.reserved ^ 0x01) { + uint16_t buffer[2]; + size_t count = 0; + + // Check to make sure the key is printable. + #ifdef USE_XKBCOMMON + if (state != NULL) { + count = keycode_to_unicode(state, keycode, buffer, sizeof(buffer) / sizeof(uint16_t)); + } + #else + count = keysym_to_unicode(keysym, buffer, sizeof(buffer) / sizeof(uint16_t)); + #endif + + unsigned int i; + for (i = 0; i < count; i++) { + // Populate key typed event. + event.time = timestamp; + event.reserved = 0x00; + + event.type = EVENT_KEY_TYPED; + event.mask = get_modifiers(); + + event.data.keyboard.keycode = VC_UNDEFINED; + event.data.keyboard.rawcode = keysym; + event.data.keyboard.keychar = buffer[i]; + + logger(LOG_LEVEL_INFO, "%s [%u]: Key %#X typed. (%lc)\n", + __FUNCTION__, __LINE__, event.data.keyboard.keycode, (uint16_t) event.data.keyboard.keychar); + + // Fire key typed event. + dispatch_event(&event); + } + } + } + else if (data->type == KeyRelease) { + // The X11 KeyCode associated with this event. + KeyCode keycode = (KeyCode) data->event.u.u.detail; + KeySym keysym = 0x00; + #ifdef USE_XKBCOMMON + if (state != NULL) { + keysym = xkb_state_key_get_one_sym(state, keycode); + } + #else + keysym = keycode_to_keysym(keycode, data->event.u.keyButtonPointer.state); + #endif + + unsigned short int scancode = keycode_to_scancode(keycode); + + // TODO If you have a better suggestion for this ugly, let me know. + if (scancode == VC_SHIFT_L) { unset_modifier_mask(MASK_SHIFT_L); } + else if (scancode == VC_SHIFT_R) { unset_modifier_mask(MASK_SHIFT_R); } + else if (scancode == VC_CONTROL_L) { unset_modifier_mask(MASK_CTRL_L); } + else if (scancode == VC_CONTROL_R) { unset_modifier_mask(MASK_CTRL_R); } + else if (scancode == VC_ALT_L) { unset_modifier_mask(MASK_ALT_L); } + else if (scancode == VC_ALT_R) { unset_modifier_mask(MASK_ALT_R); } + else if (scancode == VC_META_L) { unset_modifier_mask(MASK_META_L); } + else if (scancode == VC_META_R) { unset_modifier_mask(MASK_META_R); } + xkb_state_update_key(state, keycode, XKB_KEY_UP); + initialize_locks(); + + if ((get_modifiers() & MASK_NUM_LOCK) == 0) { + switch (scancode) { + case VC_KP_SEPARATOR: + case VC_KP_1: + case VC_KP_2: + case VC_KP_3: + case VC_KP_4: + case VC_KP_5: + case VC_KP_6: + case VC_KP_7: + case VC_KP_8: + case VC_KP_0: + case VC_KP_9: + scancode |= 0xEE00; + break; + } + } + + // Populate key released event. + event.time = timestamp; + event.reserved = 0x00; + + event.type = EVENT_KEY_RELEASED; + event.mask = get_modifiers(); + + event.data.keyboard.keycode = scancode; + event.data.keyboard.rawcode = keysym; + event.data.keyboard.keychar = CHAR_UNDEFINED; + + logger(LOG_LEVEL_INFO, "%s [%u]: Key %#X released. (%#X)\n", + __FUNCTION__, __LINE__, event.data.keyboard.keycode, event.data.keyboard.rawcode); + + // Fire key released event. + dispatch_event(&event); + } + else if (data->type == ButtonPress) { + // X11 handles wheel events as button events. + if (data->event.u.u.detail == WheelUp || data->event.u.u.detail == WheelDown + || data->event.u.u.detail == WheelLeft || data->event.u.u.detail == WheelRight) { + + // Reset the click count and previous button. + hook->input.mouse.click.count = 1; + hook->input.mouse.click.button = MOUSE_NOBUTTON; + + /* Scroll wheel release events. + * Scroll type: WHEEL_UNIT_SCROLL + * Scroll amount: 3 unit increments per notch + * Units to scroll: 3 unit increments + * Vertical unit increment: 15 pixels + */ + + // Populate mouse wheel event. + event.time = timestamp; + event.reserved = 0x00; + + event.type = EVENT_MOUSE_WHEEL; + event.mask = get_modifiers(); + + event.data.wheel.clicks = hook->input.mouse.click.count; + event.data.wheel.x = data->event.u.keyButtonPointer.rootX; + event.data.wheel.y = data->event.u.keyButtonPointer.rootY; + + #if defined(USE_XINERAMA) || defined(USE_XRANDR) + uint8_t count; + screen_data *screens = hook_create_screen_info(&count); + if (count > 1) { + event.data.wheel.x -= screens[0].x; + event.data.wheel.y -= screens[0].y; + } + + if (screens != NULL) { + free(screens); + } + #endif + + /* X11 does not have an API call for acquiring the mouse scroll type. This + * maybe part of the XInput2 (XI2) extention but I will wont know until it + * is available on my platform. For the time being we will just use the + * unit scroll value. + */ + event.data.wheel.type = WHEEL_UNIT_SCROLL; + + /* Some scroll wheel properties are available via the new XInput2 (XI2) + * extension. Unfortunately the extension is not available on my + * development platform at this time. For the time being we will just + * use the Windows default value of 3. + */ + event.data.wheel.amount = 3; + + if (data->event.u.u.detail == WheelUp || data->event.u.u.detail == WheelLeft) { + // Wheel Rotated Up and Away. + event.data.wheel.rotation = -1; + } + else { // data->event.u.u.detail == WheelDown + // Wheel Rotated Down and Towards. + event.data.wheel.rotation = 1; + } + + if (data->event.u.u.detail == WheelUp || data->event.u.u.detail == WheelDown) { + // Wheel Rotated Up or Down. + event.data.wheel.direction = WHEEL_VERTICAL_DIRECTION; + } + else { // data->event.u.u.detail == WheelLeft || data->event.u.u.detail == WheelRight + // Wheel Rotated Left or Right. + event.data.wheel.direction = WHEEL_HORIZONTAL_DIRECTION; + } + + logger(LOG_LEVEL_INFO, "%s [%u]: Mouse wheel type %u, rotated %i units in the %u direction at %u, %u.\n", + __FUNCTION__, __LINE__, event.data.wheel.type, + event.data.wheel.amount * event.data.wheel.rotation, + event.data.wheel.direction, + event.data.wheel.x, event.data.wheel.y); + + // Fire mouse wheel event. + dispatch_event(&event); + } + else { + /* This information is all static for X11, its up to the WM to + * decide how to interpret the wheel events. + */ + uint16_t button = MOUSE_NOBUTTON; + switch (data->event.u.u.detail) { + // FIXME This should use a lookup table to handle button remapping. + case Button1: + button = MOUSE_BUTTON1; + set_modifier_mask(MASK_BUTTON1); + break; + + case Button2: + button = MOUSE_BUTTON2; + set_modifier_mask(MASK_BUTTON2); + break; + + case Button3: + button = MOUSE_BUTTON3; + set_modifier_mask(MASK_BUTTON3); + break; + + case XButton1: + button = MOUSE_BUTTON4; + set_modifier_mask(MASK_BUTTON5); + break; + + case XButton2: + button = MOUSE_BUTTON5; + set_modifier_mask(MASK_BUTTON5); + break; + + default: + // Do not set modifier masks past button MASK_BUTTON5. + break; + } + + + // Track the number of clicks, the button must match the previous button. + if (button == hook->input.mouse.click.button && (long int) (timestamp - hook->input.mouse.click.time) <= hook_get_multi_click_time()) { + if (hook->input.mouse.click.count < USHRT_MAX) { + hook->input.mouse.click.count++; + } + else { + logger(LOG_LEVEL_WARN, "%s [%u]: Click count overflow detected!\n", + __FUNCTION__, __LINE__); + } + } + else { + // Reset the click count. + hook->input.mouse.click.count = 1; + + // Set the previous button. + hook->input.mouse.click.button = button; + } + + // Save this events time to calculate the hook->input.mouse.click.count. + hook->input.mouse.click.time = timestamp; + + + // Populate mouse pressed event. + event.time = timestamp; + event.reserved = 0x00; + + event.type = EVENT_MOUSE_PRESSED; + event.mask = get_modifiers(); + + event.data.mouse.button = button; + event.data.mouse.clicks = hook->input.mouse.click.count; + event.data.mouse.x = data->event.u.keyButtonPointer.rootX; + event.data.mouse.y = data->event.u.keyButtonPointer.rootY; + + #if defined(USE_XINERAMA) || defined(USE_XRANDR) + uint8_t count; + screen_data *screens = hook_create_screen_info(&count); + if (count > 1) { + event.data.mouse.x -= screens[0].x; + event.data.mouse.y -= screens[0].y; + } + + if (screens != NULL) { + free(screens); + } + #endif + + logger(LOG_LEVEL_INFO, "%s [%u]: Button %u pressed %u time(s). (%u, %u)\n", + __FUNCTION__, __LINE__, event.data.mouse.button, event.data.mouse.clicks, + event.data.mouse.x, event.data.mouse.y); + + // Fire mouse pressed event. + dispatch_event(&event); + } + } + else if (data->type == ButtonRelease) { + // X11 handles wheel events as button events. + if (data->event.u.u.detail != WheelUp && data->event.u.u.detail != WheelDown) { + /* This information is all static for X11, its up to the WM to + * decide how to interpret the wheel events. + */ + uint16_t button = MOUSE_NOBUTTON; + switch (data->event.u.u.detail) { + // FIXME This should use a lookup table to handle button remapping. + case Button1: + button = MOUSE_BUTTON1; + unset_modifier_mask(MASK_BUTTON1); + break; + + case Button2: + button = MOUSE_BUTTON2; + unset_modifier_mask(MASK_BUTTON2); + break; + + case Button3: + button = MOUSE_BUTTON3; + unset_modifier_mask(MASK_BUTTON3); + break; + + case XButton1: + button = MOUSE_BUTTON4; + unset_modifier_mask(MASK_BUTTON5); + break; + + case XButton2: + button = MOUSE_BUTTON5; + unset_modifier_mask(MASK_BUTTON5); + break; + + default: + // Do not set modifier masks past button MASK_BUTTON5. + break; + } + + // Populate mouse released event. + event.time = timestamp; + event.reserved = 0x00; + + event.type = EVENT_MOUSE_RELEASED; + event.mask = get_modifiers(); + + event.data.mouse.button = button; + event.data.mouse.clicks = hook->input.mouse.click.count; + event.data.mouse.x = data->event.u.keyButtonPointer.rootX; + event.data.mouse.y = data->event.u.keyButtonPointer.rootY; + + #if defined(USE_XINERAMA) || defined(USE_XRANDR) + uint8_t count; + screen_data *screens = hook_create_screen_info(&count); + if (count > 1) { + event.data.mouse.x -= screens[0].x; + event.data.mouse.y -= screens[0].y; + } + + if (screens != NULL) { + free(screens); + } + #endif + + logger(LOG_LEVEL_INFO, "%s [%u]: Button %u released %u time(s). (%u, %u)\n", + __FUNCTION__, __LINE__, event.data.mouse.button, + event.data.mouse.clicks, + event.data.mouse.x, event.data.mouse.y); + + // Fire mouse released event. + dispatch_event(&event); + + // If the pressed event was not consumed... + if (event.reserved ^ 0x01 && hook->input.mouse.is_dragged != true) { + // Populate mouse clicked event. + event.time = timestamp; + event.reserved = 0x00; + + event.type = EVENT_MOUSE_CLICKED; + event.mask = get_modifiers(); + + event.data.mouse.button = button; + event.data.mouse.clicks = hook->input.mouse.click.count; + event.data.mouse.x = data->event.u.keyButtonPointer.rootX; + event.data.mouse.y = data->event.u.keyButtonPointer.rootY; + + #if defined(USE_XINERAMA) || defined(USE_XRANDR) + uint8_t count; + screen_data *screens = hook_create_screen_info(&count); + if (count > 1) { + event.data.mouse.x -= screens[0].x; + event.data.mouse.y -= screens[0].y; + } + + if (screens != NULL) { + free(screens); + } + #endif + + logger(LOG_LEVEL_INFO, "%s [%u]: Button %u clicked %u time(s). (%u, %u)\n", + __FUNCTION__, __LINE__, event.data.mouse.button, + event.data.mouse.clicks, + event.data.mouse.x, event.data.mouse.y); + + // Fire mouse clicked event. + dispatch_event(&event); + } + + // Reset the number of clicks. + if (button == hook->input.mouse.click.button && (long int) (event.time - hook->input.mouse.click.time) > hook_get_multi_click_time()) { + // Reset the click count. + hook->input.mouse.click.count = 0; + } + } + } + else if (data->type == MotionNotify) { + // Reset the click count. + if (hook->input.mouse.click.count != 0 && (long int) (timestamp - hook->input.mouse.click.time) > hook_get_multi_click_time()) { + hook->input.mouse.click.count = 0; + } + + // Populate mouse move event. + event.time = timestamp; + event.reserved = 0x00; + + event.mask = get_modifiers(); + + // Check the upper half of virtual modifiers for non-zero + // values and set the mouse dragged flag. + hook->input.mouse.is_dragged = (event.mask >> 8 > 0); + if (hook->input.mouse.is_dragged) { + // Create Mouse Dragged event. + event.type = EVENT_MOUSE_DRAGGED; + } + else { + // Create a Mouse Moved event. + event.type = EVENT_MOUSE_MOVED; + } + + event.data.mouse.button = MOUSE_NOBUTTON; + event.data.mouse.clicks = hook->input.mouse.click.count; + event.data.mouse.x = data->event.u.keyButtonPointer.rootX; + event.data.mouse.y = data->event.u.keyButtonPointer.rootY; + + #if defined(USE_XINERAMA) || defined(USE_XRANDR) + uint8_t count; + screen_data *screens = hook_create_screen_info(&count); + if (count > 1) { + event.data.mouse.x -= screens[0].x; + event.data.mouse.y -= screens[0].y; + } + + if (screens != NULL) { + free(screens); + } + #endif + + logger(LOG_LEVEL_INFO, "%s [%u]: Mouse %s to %i, %i. (%#X)\n", + __FUNCTION__, __LINE__, hook->input.mouse.is_dragged ? "dragged" : "moved", + event.data.mouse.x, event.data.mouse.y, event.mask); + + // Fire mouse move event. + dispatch_event(&event); + } + else { + // In theory this *should* never execute. + logger(LOG_LEVEL_DEBUG, "%s [%u]: Unhandled X11 event: %#X.\n", + __FUNCTION__, __LINE__, (unsigned int) data->type); + } + } + else { + logger(LOG_LEVEL_WARN, "%s [%u]: Unhandled X11 hook category! (%#X)\n", + __FUNCTION__, __LINE__, recorded_data->category); + } + + // TODO There is no way to consume the XRecord event. + + XRecordFreeData(recorded_data); +} + + +static inline bool enable_key_repeate() { + // Attempt to setup detectable autorepeat. + // NOTE: is_auto_repeat is NOT stdbool! + Bool is_auto_repeat = False; + #ifdef USE_XKB + // Enable detectable auto-repeat. + XkbSetDetectableAutoRepeat(hook->ctrl.display, True, &is_auto_repeat); + #else + XAutoRepeatOn(hook->ctrl.display); + + XKeyboardState kb_state; + XGetKeyboardControl(hook->ctrl.display, &kb_state); + + is_auto_repeat = (kb_state.global_auto_repeat == AutoRepeatModeOn); + #endif + + return is_auto_repeat; +} + + +static inline int xrecord_block() { + int status = IOHOOK_FAILURE; + + // Save the data display associated with this hook so it is passed to each event. + //XPointer closeure = (XPointer) (ctrl_display); + XPointer closeure = NULL; + + #ifdef USE_XRECORD_ASYNC + // Async requires that we loop so that our thread does not return. + if (XRecordEnableContextAsync(hook->data.display, context, hook_event_proc, closeure) != 0) { + // Time in MS to sleep the runloop. + int timesleep = 100; + + // Allow the thread loop to block. + pthread_mutex_lock(&hook_xrecord_mutex); + running = true; + + do { + // Unlock the mutex from the previous iteration. + pthread_mutex_unlock(&hook_xrecord_mutex); + + XRecordProcessReplies(hook->data.display); + + // Prevent 100% CPU utilization. + struct timeval tv; + gettimeofday(&tv, NULL); + + struct timespec ts; + ts.tv_sec = time(NULL) + timesleep / 1000; + ts.tv_nsec = tv.tv_usec * 1000 + 1000 * 1000 * (timesleep % 1000); + ts.tv_sec += ts.tv_nsec / (1000 * 1000 * 1000); + ts.tv_nsec %= (1000 * 1000 * 1000); + + pthread_mutex_lock(&hook_xrecord_mutex); + pthread_cond_timedwait(&hook_xrecord_cond, &hook_xrecord_mutex, &ts); + } while (running); + + // Unlock after loop exit. + pthread_mutex_unlock(&hook_xrecord_mutex); + + // Set the exit status. + status = NULL; + } + #else + // Sync blocks until XRecordDisableContext() is called. + if (XRecordEnableContext(hook->data.display, hook->ctrl.context, hook_event_proc, closeure) != 0) { + status = IOHOOK_SUCCESS; + } + #endif + else { + logger(LOG_LEVEL_ERROR, "%s [%u]: XRecordEnableContext failure!\n", + __FUNCTION__, __LINE__); + + #ifdef USE_XRECORD_ASYNC + // Reset the running state. + pthread_mutex_lock(&hook_xrecord_mutex); + running = false; + pthread_mutex_unlock(&hook_xrecord_mutex); + #endif + + // Set the exit status. + status = IOHOOK_ERROR_X_RECORD_ENABLE_CONTEXT; + } + + return status; +} + +static int xrecord_alloc() { + int status = IOHOOK_FAILURE; + + // Make sure the data display is synchronized to prevent late event delivery! + // See Bug 42356 for more information. + // https://bugs.freedesktop.org/show_bug.cgi?id=42356#c4 + XSynchronize(hook->data.display, True); + + // Setup XRecord range. + XRecordClientSpec clients = XRecordAllClients; + + hook->data.range = XRecordAllocRange(); + if (hook->data.range != NULL) { + logger(LOG_LEVEL_DEBUG, "%s [%u]: XRecordAllocRange successful.\n", + __FUNCTION__, __LINE__); + + hook->data.range->device_events.first = KeyPress; + hook->data.range->device_events.last = MotionNotify; + + // Note that the documentation for this function is incorrect, + // hook->data.display should be used! + // See: http://www.x.org/releases/X11R7.6/doc/libXtst/recordlib.txt + hook->ctrl.context = XRecordCreateContext(hook->data.display, XRecordFromServerTime, &clients, 1, &hook->data.range, 1); + if (hook->ctrl.context != 0) { + logger(LOG_LEVEL_DEBUG, "%s [%u]: XRecordCreateContext successful.\n", + __FUNCTION__, __LINE__); + + // Block until hook_stop() is called. + status = xrecord_block(); + + // Free up the context if it was set. + XRecordFreeContext(hook->data.display, hook->ctrl.context); + } + else { + logger(LOG_LEVEL_ERROR, "%s [%u]: XRecordCreateContext failure!\n", + __FUNCTION__, __LINE__); + + // Set the exit status. + status = IOHOOK_ERROR_X_RECORD_CREATE_CONTEXT; + } + + // Free the XRecord range. + XFree(hook->data.range); + } + else { + logger(LOG_LEVEL_ERROR, "%s [%u]: XRecordAllocRange failure!\n", + __FUNCTION__, __LINE__); + + // Set the exit status. + status = IOHOOK_ERROR_X_RECORD_ALLOC_RANGE; + } + + return status; +} + +static int xrecord_query() { + int status = IOHOOK_FAILURE; + + // Check to make sure XRecord is installed and enabled. + int major, minor; + if (XRecordQueryVersion(hook->ctrl.display, &major, &minor) != 0) { + logger(LOG_LEVEL_INFO, "%s [%u]: XRecord version: %i.%i.\n", + __FUNCTION__, __LINE__, major, minor); + + status = xrecord_alloc(); + } + else { + logger(LOG_LEVEL_ERROR, "%s [%u]: XRecord is not currently available!\n", + __FUNCTION__, __LINE__); + + status = IOHOOK_ERROR_X_RECORD_NOT_FOUND; + } + + return status; +} + +static int xrecord_start() { + int status = IOHOOK_FAILURE; + + // Open the control display for XRecord. + hook->ctrl.display = XOpenDisplay(NULL); + + // Open a data display for XRecord. + // NOTE This display must be opened on the same thread as XRecord. + hook->data.display = XOpenDisplay(NULL); + if (hook->ctrl.display != NULL && hook->data.display != NULL) { + logger(LOG_LEVEL_DEBUG, "%s [%u]: XOpenDisplay successful.\n", + __FUNCTION__, __LINE__); + + bool is_auto_repeat = enable_key_repeate(); + if (is_auto_repeat) { + logger(LOG_LEVEL_DEBUG, "%s [%u]: Successfully enabled detectable autorepeat.\n", + __FUNCTION__, __LINE__); + } + else { + logger(LOG_LEVEL_WARN, "%s [%u]: Could not enable detectable auto-repeat!\n", + __FUNCTION__, __LINE__); + } + + #if defined(USE_XKBCOMMON) + // Open XCB Connection + hook->input.connection = XGetXCBConnection(hook->ctrl.display); + int xcb_status = xcb_connection_has_error(hook->input.connection); + if (xcb_status <= 0) { + // Initialize xkbcommon context. + struct xkb_context *context = xkb_context_new(XKB_CONTEXT_NO_FLAGS); + + if (context != NULL) { + hook->input.context = xkb_context_ref(context); + } + else { + logger(LOG_LEVEL_ERROR, "%s [%u]: xkb_context_new failure!\n", + __FUNCTION__, __LINE__); + } + } + else { + logger(LOG_LEVEL_ERROR, "%s [%u]: xcb_connect failure! (%d)\n", + __FUNCTION__, __LINE__, xcb_status); + } + #endif + + #ifdef USE_XKBCOMMON + state = create_xkb_state(hook->input.context, hook->input.connection); + #endif + + // Initialize starting modifiers. + initialize_modifiers(); + + status = xrecord_query(); + + #ifdef USE_XKBCOMMON + if (state != NULL) { + destroy_xkb_state(state); + } + + if (hook->input.context != NULL) { + xkb_context_unref(hook->input.context); + hook->input.context = NULL; + } + + if (hook->input.connection != NULL) { + // xcb_disconnect(hook->input.connection); + hook->input.connection = NULL; + } + #endif + } + else { + logger(LOG_LEVEL_ERROR, "%s [%u]: XOpenDisplay failure!\n", + __FUNCTION__, __LINE__); + + status = IOHOOK_ERROR_X_OPEN_DISPLAY; + } + + // Close down the XRecord data display. + if (hook->data.display != NULL) { + XCloseDisplay(hook->data.display); + hook->data.display = NULL; + } + + // Close down the XRecord control display. + if (hook->ctrl.display) { + XCloseDisplay(hook->ctrl.display); + hook->ctrl.display = NULL; + } + + return status; +} + +IOHOOK_API int hook_run() { + int status = IOHOOK_FAILURE; + + // Hook data for future cleanup. + hook = malloc(sizeof(hook_info)); + if (hook != NULL) { + hook->input.mask = 0x0000; + hook->input.mouse.is_dragged = false; + hook->input.mouse.click.count = 0; + hook->input.mouse.click.time = 0; + hook->input.mouse.click.button = MOUSE_NOBUTTON; + + status = xrecord_start(); + + // Free data associated with this hook. + free(hook); + hook = NULL; + } + else { + logger(LOG_LEVEL_ERROR, "%s [%u]: Failed to allocate memory for hook structure!\n", + __FUNCTION__, __LINE__); + + status = IOHOOK_ERROR_OUT_OF_MEMORY; + } + + logger(LOG_LEVEL_DEBUG, "%s [%u]: Something, something, something, complete.\n", + __FUNCTION__, __LINE__); + + return status; +} + +IOHOOK_API int hook_stop() { + int status = IOHOOK_FAILURE; + + if (hook != NULL && hook->ctrl.display != NULL && hook->ctrl.context != 0) { + // We need to make sure the context is still valid. + XRecordState *state = malloc(sizeof(XRecordState)); + if (state != NULL) { + if (XRecordGetContext(hook->ctrl.display, hook->ctrl.context, &state) != 0) { + // Try to exit the thread naturally. + if (state->enabled && XRecordDisableContext(hook->ctrl.display, hook->ctrl.context) != 0) { + #ifdef USE_XRECORD_ASYNC + pthread_mutex_lock(&hook_xrecord_mutex); + running = false; + pthread_cond_signal(&hook_xrecord_cond); + pthread_mutex_unlock(&hook_xrecord_mutex); + #endif + + // See Bug 42356 for more information. + // https://bugs.freedesktop.org/show_bug.cgi?id=42356#c4 + //XFlush(hook->ctrl.display); + XSync(hook->ctrl.display, False); + if (hook->ctrl.display) { + XCloseDisplay(hook->ctrl.display); + hook->ctrl.display = NULL; + } + + status = IOHOOK_SUCCESS; + } + } + else { + logger(LOG_LEVEL_ERROR, "%s [%u]: XRecordGetContext failure!\n", + __FUNCTION__, __LINE__); + + status = IOHOOK_ERROR_X_RECORD_GET_CONTEXT; + } + + free(state); + } + else { + logger(LOG_LEVEL_ERROR, "%s [%u]: Failed to allocate memory for XRecordState!\n", + __FUNCTION__, __LINE__); + + status = IOHOOK_ERROR_OUT_OF_MEMORY; + } + + return status; + } + + logger(LOG_LEVEL_DEBUG, "%s [%u]: Status: %#X.\n", + __FUNCTION__, __LINE__, status); + + return status; +} diff --git a/vendor/github.com/robotn/gohook/hook/x11/input.h b/vendor/github.com/robotn/gohook/hook/x11/input.h new file mode 100644 index 0000000..905983f --- /dev/null +++ b/vendor/github.com/robotn/gohook/hook/x11/input.h @@ -0,0 +1,86 @@ + +#define USE_XKBCOMMON 0 +//#define _included_input_helper 0 +#ifndef _included_input_helper +#define _included_input_helper + +#include +#include + +#ifdef USE_XKBCOMMON + #include + #include + #include +#endif + + +// Virtual button codes that are not defined by X11. +#define Button1 1 +#define Button2 2 +#define Button3 3 +#define WheelUp 4 +#define WheelDown 5 +#define WheelLeft 6 +#define WheelRight 7 +#define XButton1 8 +#define XButton2 9 + +/* Converts an X11 key symbol to a single Unicode character. No direct X11 + * functionality exists to provide this information. + */ +extern size_t keysym_to_unicode(KeySym keysym, uint16_t *buffer, size_t size); + +/* Convert a single Unicode character to an X11 key symbol. This function + * provides a better translation than XStringToKeysym() for Unicode characters. + */ +extern KeySym unicode_to_keysym(uint16_t unicode); + +/* Converts an X11 key code to the appropriate keyboard scan code. + */ +extern uint16_t keycode_to_scancode(KeyCode keycode); + +/* Converts a keyboard scan code to the appropriate X11 key code. + */ +extern KeyCode scancode_to_keycode(uint16_t scancode); + + +#ifdef USE_XKBCOMMON + +/* Converts an X11 key code to a Unicode character sequence. libXKBCommon support + * is required for this method. + */ +extern size_t keycode_to_unicode(struct xkb_state* state, KeyCode keycode, uint16_t *buffer, size_t size); + +/* Create a xkb_state structure and return a pointer to it. + */ +extern struct xkb_state * create_xkb_state(struct xkb_context *context, xcb_connection_t *connection); + +/* Release xkb_state structure created by create_xkb_state(). + */ +extern void destroy_xkb_state(struct xkb_state* state); + +#else + +/* Converts an X11 key code and event mask to the appropriate X11 key symbol. + * This functions in much the same way as XKeycodeToKeysym() but allows for a + * faster and more flexible lookup. + */ +extern KeySym keycode_to_keysym(KeyCode keycode, unsigned int modifier_mask); + +#endif + +/* Initialize items required for KeyCodeToKeySym() and KeySymToUnicode() + * functionality. This method is called by OnLibraryLoad() and may need to be + * called in combination with UnloadInputHelper() if the native keyboard layout + * is changed. + */ +extern void load_input_helper(); + +/* De-initialize items required for KeyCodeToKeySym() and KeySymToUnicode() + * functionality. This method is called by OnLibraryUnload() and may need to be + * called in combination with LoadInputHelper() if the native keyboard layout + * is changed. + */ +extern void unload_input_helper(); + +#endif diff --git a/vendor/github.com/robotn/gohook/hook/x11/input_c.h b/vendor/github.com/robotn/gohook/hook/x11/input_c.h new file mode 100644 index 0000000..8d7f39d --- /dev/null +++ b/vendor/github.com/robotn/gohook/hook/x11/input_c.h @@ -0,0 +1,1970 @@ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#define USE_XKB 0 +#define USE_XKBCOMMON 0 +#include +#include +#include +#include +#include +#include + +#ifdef USE_XKB +#ifdef USE_EVDEV + #include + static bool is_evdev = false; +#endif + +#include +static XkbDescPtr keyboard_map; +#else + #include + static KeySym *keyboard_map; + static int keysym_per_keycode; + static bool is_caps_lock = false, is_shift_lock = false; +#endif + +#ifdef USE_XKBCOMMON +#include +#include +#include + +#ifdef USE_XKBFILE +#include + +static struct xkb_rule_names xkb_names = { + .rules = "base", + .model = "us", + .layout = "pc105", + .variant = NULL, + .options = NULL +}; +#endif + +#endif + +#include "../logger_c.h" + +/* The follwoing two tables are based on QEMU's x_keymap.c, under the following + * terms: + * + * Copyright (C) 2003 Fabrice Bellard + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#if defined(USE_EVDEV) && defined(USE_XKB) +/* This table is generated based off the evdev -> scancode mapping above + * and the keycode mappings in the following files: + * /usr/include/linux/input.h + * /usr/share/X11/xkb/keycodes/evdev + * + * NOTE This table only works for Linux. + */ +static const uint16_t evdev_scancode_table[][2] = { + /* idx { keycode, scancode }, idx evdev code */ + /* 0 */ { VC_UNDEFINED, 0x00 }, /* 0x00 KEY_RESERVED */ + /* 1 */ { VC_UNDEFINED, 0x09 }, /* 0x01 KEY_ESC */ + /* 2 */ { VC_UNDEFINED, 0x0A }, /* 0x02 KEY_1 */ + /* 3 */ { VC_UNDEFINED, 0x0B }, /* 0x03 KEY_2 */ + /* 4 */ { VC_UNDEFINED, 0x0C }, /* 0x04 KEY_3 */ + /* 5 */ { VC_UNDEFINED, 0x0D }, /* 0x05 KEY_4 */ + /* 6 */ { VC_UNDEFINED, 0x0E }, /* 0x06 KEY_5 */ + /* 7 */ { VC_UNDEFINED, 0x0F }, /* 0x07 KEY_6 */ + /* 8 */ { VC_UNDEFINED, 0x10 }, /* 0x08 KEY_7 */ + /* 9 */ { VC_ESCAPE, 0x11 }, /* 0x09 KEY_8 */ + /* 10 */ { VC_1, 0x12 }, /* 0x0A KEY_9 */ + /* 11 */ { VC_2, 0x13 }, /* 0x0B KEY_0 */ + /* 12 */ { VC_3, 0x14 }, /* 0x0C KEY_MINUS */ + /* 13 */ { VC_4, 0x15 }, /* 0x0D KEY_EQUAL */ + /* 14 */ { VC_5, 0x16 }, /* 0x0E KEY_BACKSPACE */ + /* 15 */ { VC_6, 0x17 }, /* 0x0F KEY_TAB */ + /* 16 */ { VC_7, 0x18 }, /* 0x10 KEY_Q */ + /* 17 */ { VC_8, 0x19 }, /* 0x11 KEY_W */ + /* 18 */ { VC_9, 0x1A }, /* 0x12 KEY_E */ + /* 19 */ { VC_0, 0x1B }, /* 0x13 KEY_T */ + /* 20 */ { VC_MINUS, 0x1C }, /* 0x14 KEY_R */ + /* 21 */ { VC_EQUALS, 0x1D }, /* 0x15 KEY_Y */ + /* 22 */ { VC_BACKSPACE, 0x1E }, /* 0x16 KEY_U */ + /* 23 */ { VC_TAB, 0x1F }, /* 0x17 KEY_I */ + /* 24 */ { VC_Q, 0x20 }, /* 0x18 KEY_O */ + /* 25 */ { VC_W, 0x21 }, /* 0x19 KEY_P */ + /* 26 */ { VC_E, 0x22 }, /* 0x1A KEY_LEFTBRACE */ + /* 27 */ { VC_R, 0x23 }, /* 0x1B KEY_RIGHTBRACE */ + /* 28 */ { VC_T, 0x24 }, /* 0x1C KEY_ENTER */ + /* 29 */ { VC_Y, 0x25 }, /* 0x1D KEY_LEFTCTRL */ + /* 30 */ { VC_U, 0x26 }, /* 0x1E KEY_A */ + /* 31 */ { VC_I, 0x27 }, /* 0x1F KEY_S */ + /* 32 */ { VC_O, 0x28 }, /* 0x20 KEY_D */ + /* 33 */ { VC_P, 0x29 }, /* 0x21 KEY_F */ + /* 34 */ { VC_OPEN_BRACKET, 0x2A }, /* 0x22 KEY_G */ + /* 35 */ { VC_CLOSE_BRACKET, 0x2B }, /* 0x23 KEY_H */ + /* 36 */ { VC_ENTER, 0x2C }, /* 0x24 KEY_J */ + /* 37 */ { VC_CONTROL_L, 0x2D }, /* 0x25 KEY_K */ + /* 38 */ { VC_A, 0x2E }, /* 0x26 KEY_L */ + /* 39 */ { VC_S, 0x2F }, /* 0x27 KEY_SEMICOLON */ + /* 40 */ { VC_D, 0x30 }, /* 0x28 KEY_APOSTROPHE */ + /* 41 */ { VC_F, 0x31 }, /* 0x29 KEY_GRAVE */ + /* 42 */ { VC_G, 0x32 }, /* 0x2A KEY_LEFTSHIFT */ + /* 43 */ { VC_H, 0x33 }, /* 0x2B KEY_BACKSLASH */ + /* 44 */ { VC_J, 0x34 }, /* 0x2C KEY_Z */ + /* 45 */ { VC_K, 0x35 }, /* 0x2D KEY_X */ + /* 46 */ { VC_L, 0x36 }, /* 0x2E KEY_C */ + /* 47 */ { VC_SEMICOLON, 0x37 }, /* 0x2F KEY_V */ + /* 48 */ { VC_QUOTE, 0x38 }, /* 0x30 KEY_B */ + /* 49 */ { VC_BACKQUOTE, 0x39 }, /* 0x31 KEY_N */ + /* 50 */ { VC_SHIFT_L, 0x3A }, /* 0x32 KEY_M */ + /* 51 */ { VC_BACK_SLASH, 0x3B }, /* 0x33 KEY_COMMA */ + /* 52 */ { VC_Z, 0x3C }, /* 0x34 KEY_DOT */ + /* 53 */ { VC_X, 0x3D }, /* 0x35 KEY_SLASH */ + /* 54 */ { VC_C, 0x3E }, /* 0x36 KEY_RIGHTSHIFT */ + /* 55 */ { VC_V, 0x3F }, /* 0x37 KEY_KPASTERISK */ + /* 56 */ { VC_B, 0x40 }, /* 0x38 KEY_LEFTALT */ + /* 57 */ { VC_N, 0x41 }, /* 0x39 KEY_SPACE */ + /* 58 */ { VC_M, 0x42 }, /* 0x3A KEY_CAPSLOCK */ + /* 59 */ { VC_COMMA, 0x43 }, /* 0x3B KEY_F1 */ + /* 60 */ { VC_PERIOD, 0x44 }, /* 0x3C KEY_F2 */ + /* 61 */ { VC_SLASH, 0x45 }, /* 0x3D KEY_F3 */ + /* 62 */ { VC_SHIFT_R, 0x46 }, /* 0x3E KEY_F4 */ + /* 63 */ { VC_KP_MULTIPLY, 0x47 }, /* 0x3F KEY_F5 */ + /* 64 */ { VC_ALT_L, 0x48 }, /* 0x40 KEY_F6 */ + /* 65 */ { VC_SPACE, 0x49 }, /* 0x41 KEY_F7 */ + /* 66 */ { VC_CAPS_LOCK, 0x4A }, /* 0x42 KEY_F8 */ + /* 67 */ { VC_F1, 0x4B }, /* 0x43 KEY_F9 */ + /* 68 */ { VC_F2, 0x4C }, /* 0x44 KEY_F10 */ + /* 69 */ { VC_F3, 0x4D }, /* 0x45 KEY_NUMLOCK */ + /* 70 */ { VC_F4, 0x4E }, /* 0x46 KEY_SCROLLLOCK */ + /* 71 */ { VC_F5, 0x4F }, /* 0x47 KEY_KP7 */ + /* 72 */ { VC_F6, 0x50 }, /* 0x48 KEY_KP8 */ + /* 73 */ { VC_F7, 0x51 }, /* 0x49 KEY_KP9 */ + /* 74 */ { VC_F8, 0x52 }, /* 0x4A KEY_KPMINUS */ + /* 75 */ { VC_F9, 0x53 }, /* 0x4B KEY_KP4 */ + /* 76 */ { VC_F10, 0x54 }, /* 0x4C KEY_KP5 */ + /* 77 */ { VC_NUM_LOCK, 0x55 }, /* 0x4D KEY_KP6 */ + /* 78 */ { VC_SCROLL_LOCK, 0x56 }, /* 0x4E KEY_KPPLUS */ + /* 79 */ { VC_KP_7, 0x57 }, /* 0x4F KEY_KP1 */ + /* 80 */ { VC_KP_8, 0x58 }, /* 0x50 KEY_KP2 */ + /* 81 */ { VC_KP_9, 0x59 }, /* 0x51 KEY_KP3 */ + /* 82 */ { VC_KP_SUBTRACT, 0x5A }, /* 0x52 KEY_KP0 */ + /* 83 */ { VC_KP_4, 0x5B }, /* 0x53 KEY_KPDOT */ + /* 84 */ { VC_KP_5, 0x00 }, /* 0x54 */ + /* 85 */ { VC_KP_6, 0x00 }, /* 0x55 TODO [KEY_ZENKAKUHANKAKU][0] == [VC_?][1] */ + /* 86 */ { VC_KP_ADD, 0x00 }, /* 0x56 TODO [KEY_102ND][0] == [VC_?][1] */ + /* 87 */ { VC_KP_1, 0x5F }, /* 0x57 KEY_F11 */ + /* 88 */ { VC_KP_2, 0x60 }, /* 0x58 KEY_F12 */ + /* 89 */ { VC_KP_3, 0x00 }, /* 0x59 TODO [KEY_RO][0] == [VC_?][1] */ + /* 90 */ { VC_KP_0, 0x00 }, /* 0x5A */ + /* 91 */ { VC_KP_SEPARATOR, 0xBF }, /* 0x5B KEY_F13 */ + /* 92 */ { VC_UNDEFINED, 0xC0 }, /* 0x5C KEY_F14 */ + /* 93 */ { VC_UNDEFINED, 0xC1 }, /* 0x5D KEY_F15 */ + /* 94 */ { VC_UNDEFINED, 0x00 }, /* 0x5E TODO [KEY_MUHENKAN][0] == [VC_?][1] */ + /* 95 */ { VC_F11, 0x00 }, /* 0x5F */ + /* 96 */ { VC_F12, 0x00 }, /* 0x60 */ + + /* First 97 chars are identical to XFree86! */ + + /* 97 */ { VC_UNDEFINED, 0x00 }, /* 0x61 */ + /* 98 */ { VC_KATAKANA, 0x00 }, /* 0x62 */ + /* 99 */ { VC_HIRAGANA, 0xC2 }, /* 0x63 KEY_F16 */ + /* 100 */ { VC_KANJI, 0xC3 }, /* 0x64 KEY_F17 */ + /* 101 */ { VC_UNDEFINED, 0xC4 }, /* 0x65 KEY_F18 */ + /* 102 */ { VC_UNDEFINED, 0xC5 }, /* 0x66 KEY_F19 */ + /* 103 */ { VC_KP_COMMA, 0xC6 }, /* 0x67 KEY_F20 */ + /* 104 */ { VC_KP_ENTER, 0xC7 }, /* 0x68 KEY_F21 */ + /* 105 */ { VC_CONTROL_R, 0xC8 }, /* 0x69 KEY_F22 */ + /* 106 */ { VC_KP_DIVIDE, 0xC9 }, /* 0x6A KEY_F23 */ + /* 107 */ { VC_PRINTSCREEN, 0xCA }, /* 0x6B KEY_F24 */ + /* 108 */ { VC_ALT_R, 0x00 }, /* 0x6C */ + /* 109 */ { VC_UNDEFINED, 0x00 }, /* 0x6D */ + /* 110 */ { VC_HOME, 0x00 }, /* 0x6E */ + /* 111 */ { VC_UP, 0x00 }, /* 0x6F */ + /* 112 */ { VC_PAGE_UP, 0x62 }, /* 0x70 KEY_KATAKANA */ + /* 113 */ { VC_LEFT, 0x00 }, /* 0x71 */ + /* 114 */ { VC_RIGHT, 0x00 }, /* 0x72 */ + /* 115 */ { VC_END, 0x00 }, /* 0x73 TODO KEY_? = [VC_UNDERSCORE][1] */ + /* 116 */ { VC_DOWN, 0x00 }, /* 0x74 TODO KEY_? = [VC_FURIGANA][1] */ + /* 117 */ { VC_PAGE_DOWN, 0x00 }, /* 0x75 */ + /* 118 */ { VC_INSERT, 0x00 }, /* 0x76 TODO [KEY_KPPLUSMINUS][0] = [VC_?][1] */ + /* 119 */ { VC_DELETE, 0x00 }, /* 0x77 */ + /* 120 */ { VC_UNDEFINED, 0x00 }, /* 0x78 TODO [KEY_SCALE][0] = [VC_?][1] */ + /* 121 */ { VC_VOLUME_MUTE, 0x64 }, /* 0x79 KEY_HENKAN */ + /* 122 */ { VC_VOLUME_DOWN, 0x00 }, /* 0x7A */ + /* 123 */ { VC_VOLUME_UP, 0x63 }, /* 0x7B KEY_HIRAGANA */ + /* 124 */ { VC_POWER, 0x00 }, /* 0x7C */ + /* 125 */ { VC_KP_EQUALS, 0x84 }, /* 0x7D KEY_YEN */ + /* 126 */ { VC_UNDEFINED, 0x67 }, /* 0x7E KEY_KPJPCOMMA */ + /* 127 */ { VC_PAUSE, 0x00 }, /* 0x7F */ + + /* No Offset Offset (i & 0x007F) + 128 */ + + /* 128 */ { VC_UNDEFINED, 0 }, /* 0x80 */ + /* 129 */ { VC_UNDEFINED, 0 }, /* 0x81 */ + /* 130 */ { VC_UNDEFINED, 0 }, /* 0x82 */ + /* 131 */ { VC_UNDEFINED, 0 }, /* 0x83 */ + /* 132 */ { VC_YEN, 0 }, /* 0x84 */ + /* 133 */ { VC_META_L, 0 }, /* 0x85 */ + /* 134 */ { VC_META_R, 0 }, /* 0x86 */ + /* 135 */ { VC_CONTEXT_MENU, 0 }, /* 0x87 */ + /* 136 */ { VC_SUN_STOP, 0 }, /* 0x88 */ + /* 137 */ { VC_SUN_AGAIN, 0 }, /* 0x89 */ + /* 138 */ { VC_SUN_PROPS, 0 }, /* 0x8A */ + /* 139 */ { VC_SUN_UNDO, 0 }, /* 0x8B */ + /* 140 */ { VC_SUN_FRONT, 0 }, /* 0x8C */ + /* 141 */ { VC_SUN_COPY, 0x7D }, /* 0x8D KEY_KPEQUAL */ + /* 142 */ { VC_SUN_OPEN, 0 }, /* 0x8E */ + /* 143 */ { VC_SUN_INSERT, 0 }, /* 0x8F */ + /* 144 */ { VC_SUN_FIND, 0 }, /* 0x90 */ + /* 145 */ { VC_SUN_CUT, 0 }, /* 0x91 */ + /* 146 */ { VC_SUN_HELP, 0 }, /* 0x92 */ + /* 147 */ { VC_UNDEFINED, 0 }, /* 0x93 */ + /* 148 */ { VC_APP_CALCULATOR, 0 }, /* 0x94 */ + /* 149 */ { VC_UNDEFINED, 0 }, /* 0x95 */ + /* 150 */ { VC_SLEEP, 0 }, /* 0x96 */ + /* 151 */ { VC_UNDEFINED, 0 }, /* 0x97 */ + /* 152 */ { VC_UNDEFINED, 0 }, /* 0x98 */ + /* 153 */ { VC_UNDEFINED, 0 }, /* 0x99 */ + /* 154 */ { VC_UNDEFINED, 0 }, /* 0x9A */ + /* 155 */ { VC_UNDEFINED, 0 }, /* 0x9B */ + /* 156 */ { VC_UNDEFINED, 0x68 }, /* 0x9C KEY_KPENTER */ + /* 157 */ { VC_UNDEFINED, 0x69 }, /* 0x9D KEY_RIGHTCTRL */ + /* 158 */ { VC_UNDEFINED, 0 }, /* 0x9E */ + /* 159 */ { VC_UNDEFINED, 0 }, /* 0x9F */ + /* 160 */ { VC_UNDEFINED, 0x79 }, /* 0xA0 KEY_MUTE */ + /* 161 */ { VC_UNDEFINED, 0x94 }, /* 0xA1 KEY_CALC */ + /* 162 */ { VC_UNDEFINED, 0xA7 }, /* 0xA2 KEY_FORWARD */ + /* 163 */ { VC_UNDEFINED, 0 }, /* 0xA3 */ + /* 164 */ { VC_UNDEFINED, 0 }, /* 0xA4 */ + /* 165 */ { VC_UNDEFINED, 0 }, /* 0xA5 */ + /* 166 */ { VC_APP_MAIL, 0 }, /* 0xA6 */ + /* 167 */ { VC_MEDIA_PLAY, 0 }, /* 0xA7 */ + /* 168 */ { VC_UNDEFINED, 0 }, /* 0xA8 */ + /* 169 */ { VC_UNDEFINED, 0 }, /* 0xA9 */ + /* 170 */ { VC_UNDEFINED, 0 }, /* 0xAA */ + /* 171 */ { VC_UNDEFINED, 0 }, /* 0xAB */ + /* 172 */ { VC_UNDEFINED, 0 }, /* 0xAC */ + /* 173 */ { VC_UNDEFINED, 0 }, /* 0xAD */ + /* 174 */ { VC_UNDEFINED, 0x7A }, /* 0xAE KEY_VOLUMEDOWN */ + /* 175 */ { VC_UNDEFINED, 0 }, /* 0xAF */ + /* 176 */ { VC_UNDEFINED, 0x7B }, /* 0xB0 KEY_VOLUMEUP */ + /* 177 */ { VC_UNDEFINED, 0x00 }, /* 0xB1 */ + /* 178 */ { VC_UNDEFINED, 0xBA }, /* 0xB2 KEY_SCROLLUP */ + /* 179 */ { VC_UNDEFINED, 0x00 }, /* 0xB3 */ + /* 180 */ { VC_UNDEFINED, 0x00 }, /* 0xB4 */ + /* 181 */ { VC_UNDEFINED, 0x6A }, /* 0xB5 KEY_KPSLASH */ + /* 182 */ { VC_UNDEFINED, 0x00 }, /* 0xB6 */ + /* 183 */ { VC_UNDEFINED, 0x6B }, /* 0xB7 KEY_SYSRQ */ + /* 184 */ { VC_UNDEFINED, 0x6C }, /* 0xB8 KEY_RIGHTALT */ + /* 185 */ { VC_UNDEFINED, 0x00 }, /* 0xB9 */ + /* 186 */ { VC_BROWSER_HOME, 0x00 }, /* 0xBA */ + /* 187 */ { VC_UNDEFINED, 0x00 }, /* 0xBB */ + /* 188 */ { VC_UNDEFINED, 0x00 }, /* 0xBC */ + /* 189 */ { VC_UNDEFINED, 0x00 }, /* 0xBD */ + /* 190 */ { VC_UNDEFINED, 0x00 }, /* 0xBE */ + /* 191 */ { VC_F13, 0x00 }, /* 0xBF */ + /* 192 */ { VC_F14, 0x00 }, /* 0xC0 */ + /* 193 */ { VC_F15, 0x00 }, /* 0xC1 */ + /* 194 */ { VC_F16, 0x00 }, /* 0xC2 */ + /* 195 */ { VC_F17, 0x00 }, /* 0xC3 */ + /* 196 */ { VC_F18, 0x00 }, /* 0xC4 */ + /* 197 */ { VC_F19, 0x7F }, /* 0xC5 KEY_PAUSE */ + /* 198 */ { VC_F20, 0x00 }, /* 0xC6 */ + /* 199 */ { VC_F21, 0x6E }, /* 0xC7 KEY_HOME */ + /* 200 */ { VC_F22, 0x6F }, /* 0xC8 KEY_UP */ + /* 201 */ { VC_F23, 0x70 }, /* 0xC9 KEY_PAGEUP */ + /* 202 */ { VC_F24, 0x00 }, /* 0xCA */ + /* 203 */ { VC_UNDEFINED, 0x71 }, /* 0xCB KEY_LEFT */ + /* 204 */ { VC_UNDEFINED, 0x00 }, /* 0xCC */ + /* 205 */ { VC_UNDEFINED, 0x72 }, /* 0xCD KEY_RIGHT */ + /* 206 */ { VC_UNDEFINED, 0x00 }, /* 0xCE */ + /* 207 */ { VC_UNDEFINED, 0x73 }, /* 0xCF KEY_END */ + /* 208 */ { VC_UNDEFINED, 0x74 }, /* 0xD0 KEY_DOWN */ + /* 209 */ { VC_UNDEFINED, 0x75 }, /* 0xD1 KEY_PAGEDOWN */ + /* 210 */ { VC_UNDEFINED, 0x76 }, /* 0xD2 KEY_INSERT */ + /* 211 */ { VC_UNDEFINED, 0x77 }, /* 0xD3 KEY_DELETE */ + /* 212 */ { VC_UNDEFINED, 0x00 }, /* 0xD4 */ + /* 213 */ { VC_UNDEFINED, 0x00 }, /* 0xD5 */ + /* 214 */ { VC_UNDEFINED, 0x00 }, /* 0xD6 */ + /* 215 */ { VC_UNDEFINED, 0x00 }, /* 0xD7 */ + /* 216 */ { VC_UNDEFINED, 0x00 }, /* 0xD8 */ + /* 217 */ { VC_UNDEFINED, 0x00 }, /* 0xD9 */ + /* 218 */ { VC_UNDEFINED, 0x00 }, /* 0xDA */ + /* 219 */ { VC_UNDEFINED, 0x85 }, /* 0xDB KEY_LEFTMETA */ + /* 220 */ { VC_UNDEFINED, 0x86 }, /* 0xDC KEY_RIGHTMETA */ + /* 221 */ { VC_UNDEFINED, 0x87 }, /* 0xDD KEY_COMPOSE */ + /* 222 */ { VC_UNDEFINED, 0x7C }, /* 0xDE KEY_POWER */ + /* 223 */ { VC_UNDEFINED, 0x96 }, /* 0xDF KEY_SLEEP */ + /* 224 */ { VC_UNDEFINED, 0x00 }, /* 0xE0 */ + /* 225 */ { VC_BROWSER_SEARCH, 0x00 }, /* 0xE1 */ + /* 226 */ { VC_UNDEFINED, 0x00 }, /* 0xE2 */ + /* 227 */ { VC_UNDEFINED, 0x00 }, /* 0xE3 */ + /* 228 */ { VC_UNDEFINED, 0x00 }, /* 0xE4 */ + /* 229 */ { VC_UNDEFINED, 0xE1 }, /* 0xE5 KEY_SEARCH */ + /* 230 */ { VC_UNDEFINED, 0x00 }, /* 0xE6 */ + /* 231 */ { VC_UNDEFINED, 0x00 }, /* 0xE7 */ + /* 232 */ { VC_UNDEFINED, 0x00 }, /* 0xE8 */ + /* 233 */ { VC_UNDEFINED, 0x00 }, /* 0xE9 */ + /* 234 */ { VC_UNDEFINED, 0x00 }, /* 0xEA */ + /* 235 */ { VC_UNDEFINED, 0x00 }, /* 0xEB */ + /* 236 */ { VC_UNDEFINED, 0xA6 }, /* 0xEC KEY_BACK */ + /* 237 */ { VC_UNDEFINED, 0x00 }, /* 0xED */ + /* 238 */ { VC_UNDEFINED, 0x00 }, /* 0xEE */ + /* 239 */ { VC_UNDEFINED, 0x00 }, /* 0xEF */ + /* 240 */ { VC_UNDEFINED, 0x00 }, /* 0xF0 */ + /* 241 */ { VC_UNDEFINED, 0x00 }, /* 0xF1 */ + /* 242 */ { VC_UNDEFINED, 0x00 }, /* 0xF2 */ + /* 243 */ { VC_UNDEFINED, 0x00 }, /* 0xF3 */ + /* 244 */ { VC_UNDEFINED, 0x8E }, /* 0xF4 KEY_OPEN */ + /* 245 */ { VC_UNDEFINED, 0x92 }, /* 0xF5 KEY_HELP */ + /* 246 */ { VC_UNDEFINED, 0x8A }, /* 0xF6 KEY_PROPS */ + /* 247 */ { VC_UNDEFINED, 0x8C }, /* 0xF7 KEY_FRONT */ + /* 248 */ { VC_UNDEFINED, 0x88 }, /* 0xF8 KEY_STOP */ + /* 249 */ { VC_UNDEFINED, 0x89 }, /* 0xF9 KEY_AGAIN */ + /* 250 */ { VC_UNDEFINED, 0x8B }, /* 0xFA KEY_UNDO */ + /* 251 */ { VC_UNDEFINED, 0x91 }, /* 0xFB KEY_CUT */ + /* 252 */ { VC_UNDEFINED, 0x8D }, /* 0xFC KEY_COPY */ + /* 253 */ { VC_UNDEFINED, 0x8F }, /* 0xFD KEY_PASTE */ + /* 254 */ { VC_UNDEFINED, 0x90 }, /* 0xFE KEY_FIND */ + /* 255 */ { VC_UNDEFINED, 0x00 }, /* 0xFF */ +}; +#endif + + +/* This table is generated based off the xfree86 -> scancode mapping above + * and the keycode mappings in the following files: + * /usr/share/X11/xkb/keycodes/xfree86 + * + * TODO Everything after 157 needs to be populated with scancodes for media + * controls and internet keyboards. + */ +static const uint16_t xfree86_scancode_table[][2] = { + /* idx { keycode, scancode }, */ + /* 0 */ { VC_UNDEFINED, 0 /* */ }, // Unused + /* 1 */ { VC_UNDEFINED, 9 /* */ }, // + /* 2 */ { VC_UNDEFINED, 10 /* */ }, // + /* 3 */ { VC_UNDEFINED, 11 /* */ }, // + /* 4 */ { VC_UNDEFINED, 12 /* */ }, // + /* 5 */ { VC_UNDEFINED, 13 /* */ }, // + /* 6 */ { VC_UNDEFINED, 14 /* */ }, // + /* 7 */ { VC_UNDEFINED, 15 /* */ }, // + /* 8 */ { VC_UNDEFINED, 16 /* */ }, // + /* 9 */ { VC_ESCAPE, 17 /* */ }, // + /* 10 */ { VC_1, 18 /* */ }, // + /* 11 */ { VC_2, 19 /* */ }, // + /* 12 */ { VC_3, 20 /* */ }, // + /* 13 */ { VC_4, 21 /* */ }, // + /* 14 */ { VC_5, 22 /* */ }, // + /* 15 */ { VC_6, 23 /* */ }, // + /* 16 */ { VC_7, 24 /* */ }, // + /* 17 */ { VC_8, 25 /* */ }, // + /* 18 */ { VC_9, 26 /* */ }, // + /* 19 */ { VC_0, 27 /* */ }, // + /* 20 */ { VC_MINUS, 28 /* */ }, // + /* 21 */ { VC_EQUALS, 29 /* */ }, // + /* 22 */ { VC_BACKSPACE, 30 /* */ }, // + /* 23 */ { VC_TAB, 31 /* */ }, // + /* 24 */ { VC_Q, 32 /* */ }, // + /* 25 */ { VC_W, 33 /* */ }, // + /* 26 */ { VC_E, 34 /* */ }, // + /* 27 */ { VC_R, 35 /* */ }, // + /* 28 */ { VC_T, 36 /* */ }, // + /* 29 */ { VC_Y, 37 /* */ }, // + /* 30 */ { VC_U, 38 /* */ }, // + /* 31 */ { VC_I, 39 /* */ }, // + /* 32 */ { VC_O, 40 /* */ }, // + /* 33 */ { VC_P, 41 /* */ }, // + /* 34 */ { VC_OPEN_BRACKET, 42 /* */ }, // + /* 35 */ { VC_CLOSE_BRACKET, 43 /* */ }, // + /* 36 */ { VC_ENTER, 44 /* */ }, // + /* 37 */ { VC_CONTROL_L, 45 /* */ }, // + /* 38 */ { VC_A, 46 /* */ }, // + /* 39 */ { VC_S, 47 /* */ }, // + /* 40 */ { VC_D, 48 /* */ }, // + /* 41 */ { VC_F, 49 /* */ }, // + /* 42 */ { VC_G, 50 /* */ }, // + /* 43 */ { VC_H, 51 /* */ }, // + /* 44 */ { VC_J, 52 /* */ }, // + /* 45 */ { VC_K, 53 /* */ }, // + /* 46 */ { VC_L, 54 /* */ }, // + /* 47 */ { VC_SEMICOLON, 55 /* */ }, // + /* 48 */ { VC_QUOTE, 56 /* */ }, // + /* 49 */ { VC_BACKQUOTE, 57 /* */ }, // + /* 50 */ { VC_SHIFT_L, 58 /* */ }, // + /* 51 */ { VC_BACK_SLASH, 59 /* */ }, // + /* 52 */ { VC_Z, 60 /* */ }, // + /* 53 */ { VC_X, 61 /* */ }, // + /* 54 */ { VC_C, 62 /* */ }, // + /* 55 */ { VC_V, 63 /* */ }, // + /* 56 */ { VC_B, 64 /* */ }, // + /* 57 */ { VC_N, 65 /* */ }, // + /* 58 */ { VC_M, 66 /* */ }, // + /* 59 */ { VC_COMMA, 67 /* */ }, // + /* 60 */ { VC_PERIOD, 68 /* */ }, // + /* 61 */ { VC_SLASH, 69 /* */ }, // + /* 62 */ { VC_SHIFT_R, 70 /* */ }, // + /* 63 */ { VC_KP_MULTIPLY, 71 /* */ }, // + /* 64 */ { VC_ALT_L, 72 /* */ }, // + /* 65 */ { VC_SPACE, 73 /* */ }, // + /* 66 */ { VC_CAPS_LOCK, 74 /* */ }, // + /* 67 */ { VC_F1, 75 /* */ }, // + /* 68 */ { VC_F2, 76 /* */ }, // + /* 69 */ { VC_F3, 77 /* */ }, // + /* 70 */ { VC_F4, 78 /* */ }, // + /* 71 */ { VC_F5, 79 /* */ }, // + /* 72 */ { VC_F6, 80 /* */ }, // + /* 73 */ { VC_F7, 81 /* */ }, // + /* 74 */ { VC_F8, 82 /* */ }, // + /* 75 */ { VC_F9, 83 /* */ }, // + /* 76 */ { VC_F10, 84 /* */ }, // + /* 77 */ { VC_NUM_LOCK, 85 /* */ }, // + /* 78 */ { VC_SCROLL_LOCK, 86 /* */ }, // + /* 79 */ { VC_KP_7, 87 /* */ }, // + /* 80 */ { VC_KP_8, 88 /* */ }, // + /* 81 */ { VC_KP_9, 89 /* */ }, // + /* 82 */ { VC_KP_SUBTRACT, 90 /* */ }, // + /* 83 */ { VC_KP_4, 91 /* */ }, // + /* 84 */ { VC_KP_5, 0 }, // + /* 85 */ { VC_KP_6, 0 }, // + /* 86 */ { VC_KP_ADD, 0 }, // + /* 87 */ { VC_KP_1, 95 /* */ }, // + /* 88 */ { VC_KP_2, 96 /* */ }, + /* 89 */ { VC_KP_3, 0 }, + /* 90 */ { VC_KP_0, 0 }, + /* 91 */ { VC_KP_SEPARATOR, 118 /* */ }, + /* 92 */ { VC_UNDEFINED, 119 /* */ }, + /* 93 */ { VC_UNDEFINED, 120 /* */ }, + /* 94 */ { VC_UNDEFINED, 0 }, + /* 95 */ { VC_F11, 0 }, + /* 96 */ { VC_F12, 0 }, + + /* First 97 chars are identical to XFree86! */ + + /* 97 */ { VC_HOME, 0 }, + /* 98 */ { VC_UP, 0 }, + /* 99 */ { VC_PAGE_UP, 121 /* */ }, + /* 100 */ { VC_LEFT, 122 /* */ }, + /* 101 */ { VC_UNDEFINED, 0 }, // TODO lower brightness key? + /* 102 */ { VC_RIGHT, 0 }, + /* 103 */ { VC_END, 0 }, + /* 104 */ { VC_DOWN, 0 }, + /* 105 */ { VC_PAGE_DOWN, 0 }, + /* 106 */ { VC_INSERT, 0 }, + /* 107 */ { VC_DELETE, 0 }, + /* 108 */ { VC_KP_ENTER, 0 }, + /* 109 */ { VC_CONTROL_R, 0 }, + /* 110 */ { VC_PAUSE, 0 }, + /* 111 */ { VC_PRINTSCREEN, 0 }, + /* 112 */ { VC_KP_DIVIDE, 0 }, + /* 113 */ { VC_ALT_R, 0 }, + /* 114 */ { VC_UNDEFINED, 0 }, // VC_BREAK? + /* 115 */ { VC_META_L, 0 }, + /* 116 */ { VC_META_R, 0 }, + /* 117 */ { VC_CONTEXT_MENU, 0 }, + /* 118 */ { VC_F13, 0 }, + /* 119 */ { VC_F14, 0 }, + /* 120 */ { VC_F15, 0 }, + /* 121 */ { VC_F16, 0 }, + /* 122 */ { VC_F17, 0 }, + /* 123 */ { VC_UNDEFINED, 0 }, // FIXME What is this key? + /* 124 */ { VC_UNDEFINED, 0 }, // Never Generated + /* 125 */ { VC_UNDEFINED, 133 /* */ }, // Never Generated + /* 126 */ { VC_KP_EQUALS, 0 }, + /* 127 */ { VC_UNDEFINED, 0 }, // Never Generated + /* 128 */ { VC_UNDEFINED, 0 }, // Never Generated + /* 129 */ { VC_UNDEFINED, 0 }, // Henkan + /* 130 */ { VC_UNDEFINED, 0 }, // Some extended Internet key + /* 131 */ { VC_UNDEFINED, 0 }, // Muhenkan + /* 132 */ { VC_UNDEFINED, 0 }, // + /* 133 */ { VC_YEN, 0 }, // + /* 134 */ { VC_UNDEFINED, 0 }, // + /* 135 */ { VC_UNDEFINED, 0 }, // + /* 136 */ { VC_UNDEFINED, 0 }, // + /* 137 */ { VC_UNDEFINED, 0 }, // + /* 138 */ { VC_UNDEFINED, 0 }, // + /* 139 */ { VC_UNDEFINED, 0 }, // + /* 140 */ { VC_UNDEFINED, 0 }, // + /* 141 */ { VC_UNDEFINED, 126 }, // + /* 142 */ { VC_UNDEFINED, 0 }, // + /* 143 */ { VC_UNDEFINED, 0 }, // + /* 144 */ { VC_UNDEFINED, 0 }, // + /* 145 */ { VC_UNDEFINED, 0 }, // + /* 146 */ { VC_UNDEFINED, 0 }, // + /* 147 */ { VC_UNDEFINED, 0 }, // + /* 148 */ { VC_UNDEFINED, 0 }, // + /* 149 */ { VC_UNDEFINED, 0 }, // + /* 150 */ { VC_UNDEFINED, 0 }, // + /* 151 */ { VC_UNDEFINED, 0 }, // + /* 152 */ { VC_UNDEFINED, 0 }, // + /* 153 */ { VC_UNDEFINED, 0 }, // + /* 154 */ { VC_UNDEFINED, 0 }, // + /* 155 */ { VC_UNDEFINED, 0 }, // + /* 156 */ { VC_UNDEFINED, 108 /* */ }, // Never Generated + /* 157 */ { VC_UNDEFINED, 109 /* */ }, // + /* 158 */ { VC_UNDEFINED, 0 }, // + /* 159 */ { VC_UNDEFINED, 0 }, // + /* 160 */ { VC_UNDEFINED, 0 }, // + /* 161 */ { VC_UNDEFINED, 0 }, // + /* 162 */ { VC_UNDEFINED, 0 }, // + /* 163 */ { VC_UNDEFINED, 0 }, // + /* 164 */ { VC_UNDEFINED, 0 }, // + /* 165 */ { VC_UNDEFINED, 0 }, // + /* 166 */ { VC_UNDEFINED, 0 }, // + /* 167 */ { VC_UNDEFINED, 0 }, // + /* 168 */ { VC_UNDEFINED, 0 }, // + /* 169 */ { VC_UNDEFINED, 0 }, // + /* 170 */ { VC_UNDEFINED, 0 }, // + /* 171 */ { VC_UNDEFINED, 0 }, // + /* 172 */ { VC_UNDEFINED, 0 }, // + /* 173 */ { VC_UNDEFINED, 0 }, // + /* 174 */ { VC_UNDEFINED, 0 }, // + /* 175 */ { VC_UNDEFINED, 0 }, // + /* 176 */ { VC_UNDEFINED, 0 }, // + /* 177 */ { VC_UNDEFINED, 0 }, // + /* 178 */ { VC_UNDEFINED, 0 }, // + /* 179 */ { VC_UNDEFINED, 0 }, // + /* 180 */ { VC_UNDEFINED, 0 }, // + /* 181 */ { VC_UNDEFINED, 112 }, // + /* 182 */ { VC_UNDEFINED, 0 }, // + /* 183 */ { VC_UNDEFINED, 111 }, // + /* 184 */ { VC_UNDEFINED, 113 }, // + /* 185 */ { VC_UNDEFINED, 0 }, // + /* 186 */ { VC_UNDEFINED, 0 }, // + /* 187 */ { VC_UNDEFINED, 0 }, // + /* 188 */ { VC_UNDEFINED, 0 }, // + /* 189 */ { VC_UNDEFINED, 0 }, // + /* 190 */ { VC_UNDEFINED, 0 }, // + /* 191 */ { VC_UNDEFINED, 0 }, // + /* 192 */ { VC_UNDEFINED, 0 }, // + /* 193 */ { VC_UNDEFINED, 0 }, // + /* 194 */ { VC_UNDEFINED, 0 }, // + /* 195 */ { VC_UNDEFINED, 0 }, // + /* 196 */ { VC_UNDEFINED, 0 }, // // 114 ? + /* 197 */ { VC_UNDEFINED, 110 }, // + /* 198 */ { VC_UNDEFINED, 0 }, // + /* 199 */ { VC_UNDEFINED, 97 /* */ }, // + /* 200 */ { VC_UNDEFINED, 98 }, // + /* 201 */ { VC_UNDEFINED, 99 }, // + /* 202 */ { VC_UNDEFINED, 0 }, // + /* 204 */ { VC_UNDEFINED, 0 }, // + /* 205 */ { VC_UNDEFINED, 102 }, // + /* 206 */ { VC_UNDEFINED, 0 }, // + /* 207 */ { VC_UNDEFINED, 103 }, // + /* 208 */ { VC_UNDEFINED, 104 }, // + /* 209 */ { VC_UNDEFINED, 105 }, // + /* 210 */ { VC_UNDEFINED, 106 }, // + /* 211 */ { VC_UNDEFINED, 107 }, // + /* 212 */ { VC_UNDEFINED, 0 }, // + /* 213 */ { VC_UNDEFINED, 0 }, // + /* 214 */ { VC_UNDEFINED, 0 }, // + /* 215 */ { VC_UNDEFINED, 0 }, // + /* 216 */ { VC_UNDEFINED, 0 }, // + /* 217 */ { VC_UNDEFINED, 0 }, // + /* 218 */ { VC_UNDEFINED, 0 }, // + /* 219 */ { VC_UNDEFINED, 115 /* */ }, // + /* 220 */ { VC_UNDEFINED, 116 /* */ }, // + /* 221 */ { VC_UNDEFINED, 117 /* */ }, // + /* 222 */ { VC_UNDEFINED, 0 }, // + /* 223 */ { VC_UNDEFINED, 0 }, // + /* 224 */ { VC_UNDEFINED, 0 }, // + /* 225 */ { VC_UNDEFINED, 0 }, // + /* 226 */ { VC_UNDEFINED, 0 }, // + /* 227 */ { VC_UNDEFINED, 0 }, // + /* 228 */ { VC_UNDEFINED, 0 }, // + /* 229 */ { VC_UNDEFINED, 0 }, // + /* 230 */ { VC_UNDEFINED, 0 }, // + /* 231 */ { VC_UNDEFINED, 0 }, // + /* 232 */ { VC_UNDEFINED, 0 }, // + /* 233 */ { VC_UNDEFINED, 0 }, // + /* 234 */ { VC_UNDEFINED, 0 }, // + /* 235 */ { VC_UNDEFINED, 0 }, // + /* 236 */ { VC_UNDEFINED, 0 }, // + /* 237 */ { VC_UNDEFINED, 0 }, // + /* 238 */ { VC_UNDEFINED, 0 }, // + /* 239 */ { VC_UNDEFINED, 0 }, // + /* 240 */ { VC_UNDEFINED, 0 }, // + /* 241 */ { VC_UNDEFINED, 0 }, // + /* 242 */ { VC_UNDEFINED, 0 }, // + /* 243 */ { VC_UNDEFINED, 0 }, // + /* 244 */ { VC_UNDEFINED, 0 }, // + /* 245 */ { VC_UNDEFINED, 0 }, // + /* 246 */ { VC_UNDEFINED, 0 }, // + /* 247 */ { VC_UNDEFINED, 0 }, // + /* 248 */ { VC_UNDEFINED, 0 }, // + /* 249 */ { VC_UNDEFINED, 0 }, // + /* 250 */ { VC_UNDEFINED, 0 }, // + /* 251 */ { VC_UNDEFINED, 0 }, // + /* 252 */ { VC_UNDEFINED, 0 }, // + /* 253 */ { VC_UNDEFINED, 0 }, // + /* 254 */ { VC_UNDEFINED, 0 }, // + /* 255 */ { VC_UNDEFINED, 0 }, // + }; + + +/*********************************************************************** + * The following table contains pairs of X11 keysym values for graphical + * characters and the corresponding Unicode value. The function + * keysym_to_unicode() maps a keysym onto a Unicode value using a binary + * search, therefore keysym_unicode_table[] must remain SORTED by KeySym + * value. + * + * We allow to represent any UCS character in the range U+00000000 to + * U+00FFFFFF by a keysym value in the range 0x01000000 to 0x01FFFFFF. + * This admittedly does not cover the entire 31-bit space of UCS, but + * it does cover all of the characters up to U+10FFFF, which can be + * represented by UTF-16, and more, and it is very unlikely that higher + * UCS codes will ever be assigned by ISO. So to get Unicode character + * U+ABCD you can directly use keysym 0x1000ABCD. + * + * NOTE: The comments in the table below contain the actual character + * encoded in UTF-8, so for viewing and editing best use an editor in + * UTF-8 mode. + * + * Author: Markus G. Kuhn , University of Cambridge, + * June 1999 + * + * Special thanks to Richard Verhoeven for preparing + * an initial draft of the mapping table. + * + * This table is in the public domain. Share and enjoy! + ***********************************************************************/ +static struct codepair { + uint16_t keysym; + uint16_t unicode; +} keysym_unicode_table[] = { + { 0x01A1, 0x0104 }, /* Aogonek Ą LATIN CAPITAL LETTER A WITH OGONEK */ + { 0x01A2, 0x02D8 }, /* breve ˘ BREVE */ + { 0x01A3, 0x0141 }, /* Lstroke Ł LATIN CAPITAL LETTER L WITH STROKE */ + { 0x01A5, 0x013D }, /* Lcaron Ľ LATIN CAPITAL LETTER L WITH CARON */ + { 0x01A6, 0x015A }, /* Sacute Ś LATIN CAPITAL LETTER S WITH ACUTE */ + { 0x01A9, 0x0160 }, /* Scaron Š LATIN CAPITAL LETTER S WITH CARON */ + { 0x01AA, 0x015E }, /* Scedilla Ş LATIN CAPITAL LETTER S WITH CEDILLA */ + { 0x01AB, 0x0164 }, /* Tcaron Ť LATIN CAPITAL LETTER T WITH CARON */ + { 0x01AC, 0x0179 }, /* Zacute Ź LATIN CAPITAL LETTER Z WITH ACUTE */ + { 0x01AE, 0x017D }, /* Zcaron Ž LATIN CAPITAL LETTER Z WITH CARON */ + { 0x01AF, 0x017B }, /* Zabovedot Ż LATIN CAPITAL LETTER Z WITH DOT ABOVE */ + { 0x01B1, 0x0105 }, /* aogonek ą LATIN SMALL LETTER A WITH OGONEK */ + { 0x01B2, 0x02DB }, /* ogonek ˛ OGONEK */ + { 0x01B3, 0x0142 }, /* lstroke ł LATIN SMALL LETTER L WITH STROKE */ + { 0x01B5, 0x013E }, /* lcaron ľ LATIN SMALL LETTER L WITH CARON */ + { 0x01B6, 0x015B }, /* sacute ś LATIN SMALL LETTER S WITH ACUTE */ + { 0x01B7, 0x02C7 }, /* caron ˇ CARON */ + { 0x01B9, 0x0161 }, /* scaron š LATIN SMALL LETTER S WITH CARON */ + { 0x01BA, 0x015F }, /* scedilla ş LATIN SMALL LETTER S WITH CEDILLA */ + { 0x01BB, 0x0165 }, /* tcaron ť LATIN SMALL LETTER T WITH CARON */ + { 0x01BC, 0x017A }, /* zacute ź LATIN SMALL LETTER Z WITH ACUTE */ + { 0x01BD, 0x02DD }, /* doubleacute ˝ DOUBLE ACUTE ACCENT */ + { 0x01BE, 0x017E }, /* zcaron ž LATIN SMALL LETTER Z WITH CARON */ + { 0x01BF, 0x017C }, /* zabovedot ż LATIN SMALL LETTER Z WITH DOT ABOVE */ + { 0x01C0, 0x0154 }, /* Racute Ŕ LATIN CAPITAL LETTER R WITH ACUTE */ + { 0x01C3, 0x0102 }, /* Abreve Ă LATIN CAPITAL LETTER A WITH BREVE */ + { 0x01C5, 0x0139 }, /* Lacute Ĺ LATIN CAPITAL LETTER L WITH ACUTE */ + { 0x01C6, 0x0106 }, /* Cacute Ć LATIN CAPITAL LETTER C WITH ACUTE */ + { 0x01C8, 0x010C }, /* Ccaron Č LATIN CAPITAL LETTER C WITH CARON */ + { 0x01CA, 0x0118 }, /* Eogonek Ę LATIN CAPITAL LETTER E WITH OGONEK */ + { 0x01CC, 0x011A }, /* Ecaron Ě LATIN CAPITAL LETTER E WITH CARON */ + { 0x01CF, 0x010E }, /* Dcaron Ď LATIN CAPITAL LETTER D WITH CARON */ + { 0x01D0, 0x0110 }, /* Dstroke Đ LATIN CAPITAL LETTER D WITH STROKE */ + { 0x01D1, 0x0143 }, /* Nacute Ń LATIN CAPITAL LETTER N WITH ACUTE */ + { 0x01D2, 0x0147 }, /* Ncaron Ň LATIN CAPITAL LETTER N WITH CARON */ + { 0x01D5, 0x0150 }, /* Odoubleacute Ő LATIN CAPITAL LETTER O WITH DOUBLE ACUTE */ + { 0x01D8, 0x0158 }, /* Rcaron Ř LATIN CAPITAL LETTER R WITH CARON */ + { 0x01D9, 0x016E }, /* Uring Ů LATIN CAPITAL LETTER U WITH RING ABOVE */ + { 0x01DB, 0x0170 }, /* Udoubleacute Ű LATIN CAPITAL LETTER U WITH DOUBLE ACUTE */ + { 0x01DE, 0x0162 }, /* Tcedilla Ţ LATIN CAPITAL LETTER T WITH CEDILLA */ + { 0x01E0, 0x0155 }, /* racute ŕ LATIN SMALL LETTER R WITH ACUTE */ + { 0x01E3, 0x0103 }, /* abreve ă LATIN SMALL LETTER A WITH BREVE */ + { 0x01E5, 0x013A }, /* lacute ĺ LATIN SMALL LETTER L WITH ACUTE */ + { 0x01E6, 0x0107 }, /* cacute ć LATIN SMALL LETTER C WITH ACUTE */ + { 0x01E8, 0x010D }, /* ccaron č LATIN SMALL LETTER C WITH CARON */ + { 0x01EA, 0x0119 }, /* eogonek ę LATIN SMALL LETTER E WITH OGONEK */ + { 0x01EC, 0x011B }, /* ecaron ě LATIN SMALL LETTER E WITH CARON */ + { 0x01EF, 0x010F }, /* dcaron ď LATIN SMALL LETTER D WITH CARON */ + { 0x01F0, 0x0111 }, /* dstroke đ LATIN SMALL LETTER D WITH STROKE */ + { 0x01F1, 0x0144 }, /* nacute ń LATIN SMALL LETTER N WITH ACUTE */ + { 0x01F2, 0x0148 }, /* ncaron ň LATIN SMALL LETTER N WITH CARON */ + { 0x01F5, 0x0151 }, /* odoubleacute ő LATIN SMALL LETTER O WITH DOUBLE ACUTE */ + { 0x01F8, 0x0159 }, /* rcaron ř LATIN SMALL LETTER R WITH CARON */ + { 0x01F9, 0x016F }, /* uring ů LATIN SMALL LETTER U WITH RING ABOVE */ + { 0x01FB, 0x0171 }, /* udoubleacute ű LATIN SMALL LETTER U WITH DOUBLE ACUTE */ + { 0x01FE, 0x0163 }, /* tcedilla ţ LATIN SMALL LETTER T WITH CEDILLA */ + { 0x01FF, 0x02D9 }, /* abovedot ˙ DOT ABOVE */ + { 0x02A1, 0x0126 }, /* Hstroke Ħ LATIN CAPITAL LETTER H WITH STROKE */ + { 0x02A6, 0x0124 }, /* Hcircumflex Ĥ LATIN CAPITAL LETTER H WITH CIRCUMFLEX */ + { 0x02A9, 0x0130 }, /* Iabovedot İ LATIN CAPITAL LETTER I WITH DOT ABOVE */ + { 0x02AB, 0x011E }, /* Gbreve Ğ LATIN CAPITAL LETTER G WITH BREVE */ + { 0x02AC, 0x0134 }, /* Jcircumflex Ĵ LATIN CAPITAL LETTER J WITH CIRCUMFLEX */ + { 0x02B1, 0x0127 }, /* hstroke ħ LATIN SMALL LETTER H WITH STROKE */ + { 0x02B6, 0x0125 }, /* hcircumflex ĥ LATIN SMALL LETTER H WITH CIRCUMFLEX */ + { 0x02B9, 0x0131 }, /* idotless ı LATIN SMALL LETTER DOTLESS I */ + { 0x02BB, 0x011F }, /* gbreve ğ LATIN SMALL LETTER G WITH BREVE */ + { 0x02BC, 0x0135 }, /* jcircumflex ĵ LATIN SMALL LETTER J WITH CIRCUMFLEX */ + { 0x02C5, 0x010A }, /* Cabovedot Ċ LATIN CAPITAL LETTER C WITH DOT ABOVE */ + { 0x02C6, 0x0108 }, /* Ccircumflex Ĉ LATIN CAPITAL LETTER C WITH CIRCUMFLEX */ + { 0x02D5, 0x0120 }, /* Gabovedot Ġ LATIN CAPITAL LETTER G WITH DOT ABOVE */ + { 0x02D8, 0x011C }, /* Gcircumflex Ĝ LATIN CAPITAL LETTER G WITH CIRCUMFLEX */ + { 0x02DD, 0x016C }, /* Ubreve Ŭ LATIN CAPITAL LETTER U WITH BREVE */ + { 0x02DE, 0x015C }, /* Scircumflex Ŝ LATIN CAPITAL LETTER S WITH CIRCUMFLEX */ + { 0x02E5, 0x010B }, /* cabovedot ċ LATIN SMALL LETTER C WITH DOT ABOVE */ + { 0x02E6, 0x0109 }, /* ccircumflex ĉ LATIN SMALL LETTER C WITH CIRCUMFLEX */ + { 0x02F5, 0x0121 }, /* gabovedot ġ LATIN SMALL LETTER G WITH DOT ABOVE */ + { 0x02F8, 0x011D }, /* gcircumflex ĝ LATIN SMALL LETTER G WITH CIRCUMFLEX */ + { 0x02FD, 0x016D }, /* ubreve ŭ LATIN SMALL LETTER U WITH BREVE */ + { 0x02FE, 0x015D }, /* scircumflex ŝ LATIN SMALL LETTER S WITH CIRCUMFLEX */ + { 0x03A2, 0x0138 }, /* kra ĸ LATIN SMALL LETTER KRA */ + { 0x03A3, 0x0156 }, /* Rcedilla Ŗ LATIN CAPITAL LETTER R WITH CEDILLA */ + { 0x03A5, 0x0128 }, /* Itilde Ĩ LATIN CAPITAL LETTER I WITH TILDE */ + { 0x03A6, 0x013B }, /* Lcedilla Ļ LATIN CAPITAL LETTER L WITH CEDILLA */ + { 0x03AA, 0x0112 }, /* Emacron Ē LATIN CAPITAL LETTER E WITH MACRON */ + { 0x03AB, 0x0122 }, /* Gcedilla Ģ LATIN CAPITAL LETTER G WITH CEDILLA */ + { 0x03AC, 0x0166 }, /* Tslash Ŧ LATIN CAPITAL LETTER T WITH STROKE */ + { 0x03B3, 0x0157 }, /* rcedilla ŗ LATIN SMALL LETTER R WITH CEDILLA */ + { 0x03B5, 0x0129 }, /* itilde ĩ LATIN SMALL LETTER I WITH TILDE */ + { 0x03B6, 0x013C }, /* lcedilla ļ LATIN SMALL LETTER L WITH CEDILLA */ + { 0x03BA, 0x0113 }, /* emacron ē LATIN SMALL LETTER E WITH MACRON */ + { 0x03BB, 0x0123 }, /* gcedilla ģ LATIN SMALL LETTER G WITH CEDILLA */ + { 0x03BC, 0x0167 }, /* tslash ŧ LATIN SMALL LETTER T WITH STROKE */ + { 0x03BD, 0x014A }, /* ENG Ŋ LATIN CAPITAL LETTER ENG */ + { 0x03BF, 0x014B }, /* eng ŋ LATIN SMALL LETTER ENG */ + { 0x03C0, 0x0100 }, /* Amacron Ā LATIN CAPITAL LETTER A WITH MACRON */ + { 0x03C7, 0x012E }, /* Iogonek Į LATIN CAPITAL LETTER I WITH OGONEK */ + { 0x03CC, 0x0116 }, /* Eabovedot Ė LATIN CAPITAL LETTER E WITH DOT ABOVE */ + { 0x03CF, 0x012A }, /* Imacron Ī LATIN CAPITAL LETTER I WITH MACRON */ + { 0x03D1, 0x0145 }, /* Ncedilla Ņ LATIN CAPITAL LETTER N WITH CEDILLA */ + { 0x03D2, 0x014C }, /* Omacron Ō LATIN CAPITAL LETTER O WITH MACRON */ + { 0x03D3, 0x0136 }, /* Kcedilla Ķ LATIN CAPITAL LETTER K WITH CEDILLA */ + { 0x03D9, 0x0172 }, /* Uogonek Ų LATIN CAPITAL LETTER U WITH OGONEK */ + { 0x03DD, 0x0168 }, /* Utilde Ũ LATIN CAPITAL LETTER U WITH TILDE */ + { 0x03DE, 0x016A }, /* Umacron Ū LATIN CAPITAL LETTER U WITH MACRON */ + { 0x03E0, 0x0101 }, /* amacron ā LATIN SMALL LETTER A WITH MACRON */ + { 0x03E7, 0x012F }, /* iogonek į LATIN SMALL LETTER I WITH OGONEK */ + { 0x03EC, 0x0117 }, /* eabovedot ė LATIN SMALL LETTER E WITH DOT ABOVE */ + { 0x03EF, 0x012B }, /* imacron ī LATIN SMALL LETTER I WITH MACRON */ + { 0x03F1, 0x0146 }, /* ncedilla ņ LATIN SMALL LETTER N WITH CEDILLA */ + { 0x03F2, 0x014D }, /* omacron ō LATIN SMALL LETTER O WITH MACRON */ + { 0x03F3, 0x0137 }, /* kcedilla ķ LATIN SMALL LETTER K WITH CEDILLA */ + { 0x03F9, 0x0173 }, /* uogonek ų LATIN SMALL LETTER U WITH OGONEK */ + { 0x03FD, 0x0169 }, /* utilde ũ LATIN SMALL LETTER U WITH TILDE */ + { 0x03FE, 0x016B }, /* umacron ū LATIN SMALL LETTER U WITH MACRON */ + { 0x047E, 0x203E }, /* overline ‾ OVERLINE */ + { 0x04A1, 0x3002 }, /* kana_fullstop 。 IDEOGRAPHIC FULL STOP */ + { 0x04A2, 0x300C }, /* kana_openingbracket 「 LEFT CORNER BRACKET */ + { 0x04A3, 0x300D }, /* kana_closingbracket 」 RIGHT CORNER BRACKET */ + { 0x04A4, 0x3001 }, /* kana_comma 、 IDEOGRAPHIC COMMA */ + { 0x04A5, 0x30FB }, /* kana_conjunctive ・ KATAKANA MIDDLE DOT */ + { 0x04A6, 0x30F2 }, /* kana_WO ヲ KATAKANA LETTER WO */ + { 0x04A7, 0x30A1 }, /* kana_a ァ KATAKANA LETTER SMALL A */ + { 0x04A8, 0x30A3 }, /* kana_i ィ KATAKANA LETTER SMALL I */ + { 0x04A9, 0x30A5 }, /* kana_u ゥ KATAKANA LETTER SMALL U */ + { 0x04AA, 0x30A7 }, /* kana_e ェ KATAKANA LETTER SMALL E */ + { 0x04AB, 0x30A9 }, /* kana_o ォ KATAKANA LETTER SMALL O */ + { 0x04AC, 0x30E3 }, /* kana_ya ャ KATAKANA LETTER SMALL YA */ + { 0x04AD, 0x30E5 }, /* kana_yu ュ KATAKANA LETTER SMALL YU */ + { 0x04AE, 0x30E7 }, /* kana_yo ョ KATAKANA LETTER SMALL YO */ + { 0x04AF, 0x30C3 }, /* kana_tsu ッ KATAKANA LETTER SMALL TU */ + { 0x04B0, 0x30FC }, /* prolongedsound ー KATAKANA-HIRAGANA PROLONGED SOUND MARK */ + { 0x04B1, 0x30A2 }, /* kana_A ア KATAKANA LETTER A */ + { 0x04B2, 0x30A4 }, /* kana_I イ KATAKANA LETTER I */ + { 0x04B3, 0x30A6 }, /* kana_U ウ KATAKANA LETTER U */ + { 0x04B4, 0x30A8 }, /* kana_E エ KATAKANA LETTER E */ + { 0x04B5, 0x30AA }, /* kana_O オ KATAKANA LETTER O */ + { 0x04B6, 0x30AB }, /* kana_KA カ KATAKANA LETTER KA */ + { 0x04B7, 0x30AD }, /* kana_KI キ KATAKANA LETTER KI */ + { 0x04B8, 0x30AF }, /* kana_KU ク KATAKANA LETTER KU */ + { 0x04B9, 0x30B1 }, /* kana_KE ケ KATAKANA LETTER KE */ + { 0x04BA, 0x30B3 }, /* kana_KO コ KATAKANA LETTER KO */ + { 0x04BB, 0x30B5 }, /* kana_SA サ KATAKANA LETTER SA */ + { 0x04BC, 0x30B7 }, /* kana_SHI シ KATAKANA LETTER SI */ + { 0x04BD, 0x30B9 }, /* kana_SU ス KATAKANA LETTER SU */ + { 0x04BE, 0x30BB }, /* kana_SE セ KATAKANA LETTER SE */ + { 0x04BF, 0x30BD }, /* kana_SO ソ KATAKANA LETTER SO */ + { 0x04C0, 0x30BF }, /* kana_TA タ KATAKANA LETTER TA */ + { 0x04C1, 0x30C1 }, /* kana_CHI チ KATAKANA LETTER TI */ + { 0x04C2, 0x30C4 }, /* kana_TSU ツ KATAKANA LETTER TU */ + { 0x04C3, 0x30C6 }, /* kana_TE テ KATAKANA LETTER TE */ + { 0x04C4, 0x30C8 }, /* kana_TO ト KATAKANA LETTER TO */ + { 0x04C5, 0x30CA }, /* kana_NA ナ KATAKANA LETTER NA */ + { 0x04C6, 0x30CB }, /* kana_NI ニ KATAKANA LETTER NI */ + { 0x04C7, 0x30CC }, /* kana_NU ヌ KATAKANA LETTER NU */ + { 0x04C8, 0x30CD }, /* kana_NE ネ KATAKANA LETTER NE */ + { 0x04C9, 0x30CE }, /* kana_NO ノ KATAKANA LETTER NO */ + { 0x04CA, 0x30CF }, /* kana_HA ハ KATAKANA LETTER HA */ + { 0x04CB, 0x30D2 }, /* kana_HI ヒ KATAKANA LETTER HI */ + { 0x04CC, 0x30D5 }, /* kana_FU フ KATAKANA LETTER HU */ + { 0x04CD, 0x30D8 }, /* kana_HE ヘ KATAKANA LETTER HE */ + { 0x04CE, 0x30DB }, /* kana_HO ホ KATAKANA LETTER HO */ + { 0x04CF, 0x30DE }, /* kana_MA マ KATAKANA LETTER MA */ + { 0x04D0, 0x30DF }, /* kana_MI ミ KATAKANA LETTER MI */ + { 0x04D1, 0x30E0 }, /* kana_MU ム KATAKANA LETTER MU */ + { 0x04D2, 0x30E1 }, /* kana_ME メ KATAKANA LETTER ME */ + { 0x04D3, 0x30E2 }, /* kana_MO モ KATAKANA LETTER MO */ + { 0x04D4, 0x30E4 }, /* kana_YA ヤ KATAKANA LETTER YA */ + { 0x04D5, 0x30E6 }, /* kana_YU ユ KATAKANA LETTER YU */ + { 0x04D6, 0x30E8 }, /* kana_YO ヨ KATAKANA LETTER YO */ + { 0x04D7, 0x30E9 }, /* kana_RA ラ KATAKANA LETTER RA */ + { 0x04D8, 0x30EA }, /* kana_RI リ KATAKANA LETTER RI */ + { 0x04D9, 0x30EB }, /* kana_RU ル KATAKANA LETTER RU */ + { 0x04DA, 0x30EC }, /* kana_RE レ KATAKANA LETTER RE */ + { 0x04DB, 0x30ED }, /* kana_RO ロ KATAKANA LETTER RO */ + { 0x04DC, 0x30EF }, /* kana_WA ワ KATAKANA LETTER WA */ + { 0x04DD, 0x30F3 }, /* kana_N ン KATAKANA LETTER N */ + { 0x04DE, 0x309B }, /* voicedsound ゛ KATAKANA-HIRAGANA VOICED SOUND MARK */ + { 0x04DF, 0x309C }, /* semivoicedsound ゜ KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK */ + { 0x05AC, 0x060C }, /* Arabic_comma ، ARABIC COMMA */ + { 0x05BB, 0x061B }, /* Arabic_semicolon ؛ ARABIC SEMICOLON */ + { 0x05BF, 0x061F }, /* Arabic_question_mark ؟ ARABIC QUESTION MARK */ + { 0x05C1, 0x0621 }, /* Arabic_hamza ء ARABIC LETTER HAMZA */ + { 0x05C2, 0x0622 }, /* Arabic_maddaonalef آ ARABIC LETTER ALEF WITH MADDA ABOVE */ + { 0x05C3, 0x0623 }, /* Arabic_hamzaonalef أ ARABIC LETTER ALEF WITH HAMZA ABOVE */ + { 0x05C4, 0x0624 }, /* Arabic_hamzaonwaw ؤ ARABIC LETTER WAW WITH HAMZA ABOVE */ + { 0x05C5, 0x0625 }, /* Arabic_hamzaunderalef إ ARABIC LETTER ALEF WITH HAMZA BELOW */ + { 0x05C6, 0x0626 }, /* Arabic_hamzaonyeh ئ ARABIC LETTER YEH WITH HAMZA ABOVE */ + { 0x05C7, 0x0627 }, /* Arabic_alef ا ARABIC LETTER ALEF */ + { 0x05C8, 0x0628 }, /* Arabic_beh ب ARABIC LETTER BEH */ + { 0x05C9, 0x0629 }, /* Arabic_tehmarbuta ة ARABIC LETTER TEH MARBUTA */ + { 0x05CA, 0x062A }, /* Arabic_teh ت ARABIC LETTER TEH */ + { 0x05CB, 0x062B }, /* Arabic_theh ث ARABIC LETTER THEH */ + { 0x05CC, 0x062C }, /* Arabic_jeem ج ARABIC LETTER JEEM */ + { 0x05CD, 0x062D }, /* Arabic_hah ح ARABIC LETTER HAH */ + { 0x05CE, 0x062E }, /* Arabic_khah خ ARABIC LETTER KHAH */ + { 0x05CF, 0x062F }, /* Arabic_dal د ARABIC LETTER DAL */ + { 0x05D0, 0x0630 }, /* Arabic_thal ذ ARABIC LETTER THAL */ + { 0x05D1, 0x0631 }, /* Arabic_ra ر ARABIC LETTER REH */ + { 0x05D2, 0x0632 }, /* Arabic_zain ز ARABIC LETTER ZAIN */ + { 0x05D3, 0x0633 }, /* Arabic_seen س ARABIC LETTER SEEN */ + { 0x05D4, 0x0634 }, /* Arabic_sheen ش ARABIC LETTER SHEEN */ + { 0x05D5, 0x0635 }, /* Arabic_sad ص ARABIC LETTER SAD */ + { 0x05D6, 0x0636 }, /* Arabic_dad ض ARABIC LETTER DAD */ + { 0x05D7, 0x0637 }, /* Arabic_tah ط ARABIC LETTER TAH */ + { 0x05D8, 0x0638 }, /* Arabic_zah ظ ARABIC LETTER ZAH */ + { 0x05D9, 0x0639 }, /* Arabic_ain ع ARABIC LETTER AIN */ + { 0x05DA, 0x063A }, /* Arabic_ghain غ ARABIC LETTER GHAIN */ + { 0x05E0, 0x0640 }, /* Arabic_tatweel ـ ARABIC TATWEEL */ + { 0x05E1, 0x0641 }, /* Arabic_feh ف ARABIC LETTER FEH */ + { 0x05E2, 0x0642 }, /* Arabic_qaf ق ARABIC LETTER QAF */ + { 0x05E3, 0x0643 }, /* Arabic_kaf ك ARABIC LETTER KAF */ + { 0x05E4, 0x0644 }, /* Arabic_lam ل ARABIC LETTER LAM */ + { 0x05E5, 0x0645 }, /* Arabic_meem م ARABIC LETTER MEEM */ + { 0x05E6, 0x0646 }, /* Arabic_noon ن ARABIC LETTER NOON */ + { 0x05E7, 0x0647 }, /* Arabic_ha ه ARABIC LETTER HEH */ + { 0x05E8, 0x0648 }, /* Arabic_waw و ARABIC LETTER WAW */ + { 0x05E9, 0x0649 }, /* Arabic_alefmaksura ى ARABIC LETTER ALEF MAKSURA */ + { 0x05EA, 0x064A }, /* Arabic_yeh ي ARABIC LETTER YEH */ + { 0x05EB, 0x064B }, /* Arabic_fathatan ً ARABIC FATHATAN */ + { 0x05EC, 0x064C }, /* Arabic_dammatan ٌ ARABIC DAMMATAN */ + { 0x05ED, 0x064D }, /* Arabic_kasratan ٍ ARABIC KASRATAN */ + { 0x05EE, 0x064E }, /* Arabic_fatha َ ARABIC FATHA */ + { 0x05EF, 0x064F }, /* Arabic_damma ُ ARABIC DAMMA */ + { 0x05F0, 0x0650 }, /* Arabic_kasra ِ ARABIC KASRA */ + { 0x05F1, 0x0651 }, /* Arabic_shadda ّ ARABIC SHADDA */ + { 0x05F2, 0x0652 }, /* Arabic_sukun ْ ARABIC SUKUN */ + { 0x06A1, 0x0452 }, /* Serbian_dje ђ CYRILLIC SMALL LETTER DJE */ + { 0x06A2, 0x0453 }, /* Macedonia_gje ѓ CYRILLIC SMALL LETTER GJE */ + { 0x06A3, 0x0451 }, /* Cyrillic_io ё CYRILLIC SMALL LETTER IO */ + { 0x06A4, 0x0454 }, /* Ukrainian_ie є CYRILLIC SMALL LETTER UKRAINIAN IE */ + { 0x06A5, 0x0455 }, /* Macedonia_dse ѕ CYRILLIC SMALL LETTER DZE */ + { 0x06A6, 0x0456 }, /* Ukrainian_i і CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I */ + { 0x06A7, 0x0457 }, /* Ukrainian_yi ї CYRILLIC SMALL LETTER YI */ + { 0x06A8, 0x0458 }, /* Cyrillic_je ј CYRILLIC SMALL LETTER JE */ + { 0x06A9, 0x0459 }, /* Cyrillic_lje љ CYRILLIC SMALL LETTER LJE */ + { 0x06AA, 0x045A }, /* Cyrillic_nje њ CYRILLIC SMALL LETTER NJE */ + { 0x06AB, 0x045B }, /* Serbian_tshe ћ CYRILLIC SMALL LETTER TSHE */ + { 0x06AC, 0x045C }, /* Macedonia_kje ќ CYRILLIC SMALL LETTER KJE */ + { 0x06AE, 0x045E }, /* Byelorussian_shortu ў CYRILLIC SMALL LETTER SHORT U */ + { 0x06AF, 0x045F }, /* Cyrillic_dzhe џ CYRILLIC SMALL LETTER DZHE */ + { 0x06B0, 0x2116 }, /* numerosign № NUMERO SIGN */ + { 0x06B1, 0x0402 }, /* Serbian_DJE Ђ CYRILLIC CAPITAL LETTER DJE */ + { 0x06B2, 0x0403 }, /* Macedonia_GJE Ѓ CYRILLIC CAPITAL LETTER GJE */ + { 0x06B3, 0x0401 }, /* Cyrillic_IO Ё CYRILLIC CAPITAL LETTER IO */ + { 0x06B4, 0x0404 }, /* Ukrainian_IE Є CYRILLIC CAPITAL LETTER UKRAINIAN IE */ + { 0x06B5, 0x0405 }, /* Macedonia_DSE Ѕ CYRILLIC CAPITAL LETTER DZE */ + { 0x06B6, 0x0406 }, /* Ukrainian_I І CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I */ + { 0x06B7, 0x0407 }, /* Ukrainian_YI Ї CYRILLIC CAPITAL LETTER YI */ + { 0x06B8, 0x0408 }, /* Cyrillic_JE Ј CYRILLIC CAPITAL LETTER JE */ + { 0x06B9, 0x0409 }, /* Cyrillic_LJE Љ CYRILLIC CAPITAL LETTER LJE */ + { 0x06BA, 0x040A }, /* Cyrillic_NJE Њ CYRILLIC CAPITAL LETTER NJE */ + { 0x06BB, 0x040B }, /* Serbian_TSHE Ћ CYRILLIC CAPITAL LETTER TSHE */ + { 0x06BC, 0x040C }, /* Macedonia_KJE Ќ CYRILLIC CAPITAL LETTER KJE */ + { 0x06BE, 0x040E }, /* Byelorussian_SHORTU Ў CYRILLIC CAPITAL LETTER SHORT U */ + { 0x06BF, 0x040F }, /* Cyrillic_DZHE Џ CYRILLIC CAPITAL LETTER DZHE */ + { 0x06C0, 0x044E }, /* Cyrillic_yu ю CYRILLIC SMALL LETTER YU */ + { 0x06C1, 0x0430 }, /* Cyrillic_a а CYRILLIC SMALL LETTER A */ + { 0x06C2, 0x0431 }, /* Cyrillic_be б CYRILLIC SMALL LETTER BE */ + { 0x06C3, 0x0446 }, /* Cyrillic_tse ц CYRILLIC SMALL LETTER TSE */ + { 0x06C4, 0x0434 }, /* Cyrillic_de д CYRILLIC SMALL LETTER DE */ + { 0x06C5, 0x0435 }, /* Cyrillic_ie е CYRILLIC SMALL LETTER IE */ + { 0x06C6, 0x0444 }, /* Cyrillic_ef ф CYRILLIC SMALL LETTER EF */ + { 0x06C7, 0x0433 }, /* Cyrillic_ghe г CYRILLIC SMALL LETTER GHE */ + { 0x06C8, 0x0445 }, /* Cyrillic_ha х CYRILLIC SMALL LETTER HA */ + { 0x06C9, 0x0438 }, /* Cyrillic_i и CYRILLIC SMALL LETTER I */ + { 0x06CA, 0x0439 }, /* Cyrillic_shorti й CYRILLIC SMALL LETTER SHORT I */ + { 0x06CB, 0x043A }, /* Cyrillic_ka к CYRILLIC SMALL LETTER KA */ + { 0x06CC, 0x043B }, /* Cyrillic_el л CYRILLIC SMALL LETTER EL */ + { 0x06CD, 0x043C }, /* Cyrillic_em м CYRILLIC SMALL LETTER EM */ + { 0x06CE, 0x043D }, /* Cyrillic_en н CYRILLIC SMALL LETTER EN */ + { 0x06CF, 0x043E }, /* Cyrillic_o о CYRILLIC SMALL LETTER O */ + { 0x06D0, 0x043F }, /* Cyrillic_pe п CYRILLIC SMALL LETTER PE */ + { 0x06D1, 0x044F }, /* Cyrillic_ya я CYRILLIC SMALL LETTER YA */ + { 0x06D2, 0x0440 }, /* Cyrillic_er р CYRILLIC SMALL LETTER ER */ + { 0x06D3, 0x0441 }, /* Cyrillic_es с CYRILLIC SMALL LETTER ES */ + { 0x06D4, 0x0442 }, /* Cyrillic_te т CYRILLIC SMALL LETTER TE */ + { 0x06D5, 0x0443 }, /* Cyrillic_u у CYRILLIC SMALL LETTER U */ + { 0x06D6, 0x0436 }, /* Cyrillic_zhe ж CYRILLIC SMALL LETTER ZHE */ + { 0x06D7, 0x0432 }, /* Cyrillic_ve в CYRILLIC SMALL LETTER VE */ + { 0x06D8, 0x044C }, /* Cyrillic_softsign ь CYRILLIC SMALL LETTER SOFT SIGN */ + { 0x06D9, 0x044B }, /* Cyrillic_yeru ы CYRILLIC SMALL LETTER YERU */ + { 0x06DA, 0x0437 }, /* Cyrillic_ze з CYRILLIC SMALL LETTER ZE */ + { 0x06DB, 0x0448 }, /* Cyrillic_sha ш CYRILLIC SMALL LETTER SHA */ + { 0x06DC, 0x044D }, /* Cyrillic_e э CYRILLIC SMALL LETTER E */ + { 0x06DD, 0x0449 }, /* Cyrillic_shcha щ CYRILLIC SMALL LETTER SHCHA */ + { 0x06DE, 0x0447 }, /* Cyrillic_che ч CYRILLIC SMALL LETTER CHE */ + { 0x06DF, 0x044A }, /* Cyrillic_hardsign ъ CYRILLIC SMALL LETTER HARD SIGN */ + { 0x06E0, 0x042E }, /* Cyrillic_YU Ю CYRILLIC CAPITAL LETTER YU */ + { 0x06E1, 0x0410 }, /* Cyrillic_A А CYRILLIC CAPITAL LETTER A */ + { 0x06E2, 0x0411 }, /* Cyrillic_BE Б CYRILLIC CAPITAL LETTER BE */ + { 0x06E3, 0x0426 }, /* Cyrillic_TSE Ц CYRILLIC CAPITAL LETTER TSE */ + { 0x06E4, 0x0414 }, /* Cyrillic_DE Д CYRILLIC CAPITAL LETTER DE */ + { 0x06E5, 0x0415 }, /* Cyrillic_IE Е CYRILLIC CAPITAL LETTER IE */ + { 0x06E6, 0x0424 }, /* Cyrillic_EF Ф CYRILLIC CAPITAL LETTER EF */ + { 0x06E7, 0x0413 }, /* Cyrillic_GHE Г CYRILLIC CAPITAL LETTER GHE */ + { 0x06E8, 0x0425 }, /* Cyrillic_HA Х CYRILLIC CAPITAL LETTER HA */ + { 0x06E9, 0x0418 }, /* Cyrillic_I И CYRILLIC CAPITAL LETTER I */ + { 0x06EA, 0x0419 }, /* Cyrillic_SHORTI Й CYRILLIC CAPITAL LETTER SHORT I */ + { 0x06EB, 0x041A }, /* Cyrillic_KA К CYRILLIC CAPITAL LETTER KA */ + { 0x06EC, 0x041B }, /* Cyrillic_EL Л CYRILLIC CAPITAL LETTER EL */ + { 0x06ED, 0x041C }, /* Cyrillic_EM М CYRILLIC CAPITAL LETTER EM */ + { 0x06EE, 0x041D }, /* Cyrillic_EN Н CYRILLIC CAPITAL LETTER EN */ + { 0x06EF, 0x041E }, /* Cyrillic_O О CYRILLIC CAPITAL LETTER O */ + { 0x06F0, 0x041F }, /* Cyrillic_PE П CYRILLIC CAPITAL LETTER PE */ + { 0x06F1, 0x042F }, /* Cyrillic_YA Я CYRILLIC CAPITAL LETTER YA */ + { 0x06F2, 0x0420 }, /* Cyrillic_ER Р CYRILLIC CAPITAL LETTER ER */ + { 0x06F3, 0x0421 }, /* Cyrillic_ES С CYRILLIC CAPITAL LETTER ES */ + { 0x06F4, 0x0422 }, /* Cyrillic_TE Т CYRILLIC CAPITAL LETTER TE */ + { 0x06F5, 0x0423 }, /* Cyrillic_U У CYRILLIC CAPITAL LETTER U */ + { 0x06F6, 0x0416 }, /* Cyrillic_ZHE Ж CYRILLIC CAPITAL LETTER ZHE */ + { 0x06F7, 0x0412 }, /* Cyrillic_VE В CYRILLIC CAPITAL LETTER VE */ + { 0x06F8, 0x042C }, /* Cyrillic_SOFTSIGN Ь CYRILLIC CAPITAL LETTER SOFT SIGN */ + { 0x06F9, 0x042B }, /* Cyrillic_YERU Ы CYRILLIC CAPITAL LETTER YERU */ + { 0x06FA, 0x0417 }, /* Cyrillic_ZE З CYRILLIC CAPITAL LETTER ZE */ + { 0x06FB, 0x0428 }, /* Cyrillic_SHA Ш CYRILLIC CAPITAL LETTER SHA */ + { 0x06FC, 0x042D }, /* Cyrillic_E Э CYRILLIC CAPITAL LETTER E */ + { 0x06FD, 0x0429 }, /* Cyrillic_SHCHA Щ CYRILLIC CAPITAL LETTER SHCHA */ + { 0x06FE, 0x0427 }, /* Cyrillic_CHE Ч CYRILLIC CAPITAL LETTER CHE */ + { 0x06FF, 0x042A }, /* Cyrillic_HARDSIGN Ъ CYRILLIC CAPITAL LETTER HARD SIGN */ + { 0x07A1, 0x0386 }, /* Greek_ALPHAaccent Ά GREEK CAPITAL LETTER ALPHA WITH TONOS */ + { 0x07A2, 0x0388 }, /* Greek_EPSILONaccent Έ GREEK CAPITAL LETTER EPSILON WITH TONOS */ + { 0x07A3, 0x0389 }, /* Greek_ETAaccent Ή GREEK CAPITAL LETTER ETA WITH TONOS */ + { 0x07A4, 0x038A }, /* Greek_IOTAaccent Ί GREEK CAPITAL LETTER IOTA WITH TONOS */ + { 0x07A5, 0x03AA }, /* Greek_IOTAdiaeresis Ϊ GREEK CAPITAL LETTER IOTA WITH DIALYTIKA */ + { 0x07A7, 0x038C }, /* Greek_OMICRONaccent Ό GREEK CAPITAL LETTER OMICRON WITH TONOS */ + { 0x07A8, 0x038E }, /* Greek_UPSILONaccent Ύ GREEK CAPITAL LETTER UPSILON WITH TONOS */ + { 0x07A9, 0x03AB }, /* Greek_UPSILONdieresis Ϋ GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA */ + { 0x07AB, 0x038F }, /* Greek_OMEGAaccent Ώ GREEK CAPITAL LETTER OMEGA WITH TONOS */ + { 0x07AE, 0x0385 }, /* Greek_accentdieresis ΅ GREEK DIALYTIKA TONOS */ + { 0x07AF, 0x2015 }, /* Greek_horizbar ― HORIZONTAL BAR */ + { 0x07B1, 0x03AC }, /* Greek_alphaaccent ά GREEK SMALL LETTER ALPHA WITH TONOS */ + { 0x07B2, 0x03AD }, /* Greek_epsilonaccent έ GREEK SMALL LETTER EPSILON WITH TONOS */ + { 0x07B3, 0x03AE }, /* Greek_etaaccent ή GREEK SMALL LETTER ETA WITH TONOS */ + { 0x07B4, 0x03AF }, /* Greek_iotaaccent ί GREEK SMALL LETTER IOTA WITH TONOS */ + { 0x07B5, 0x03CA }, /* Greek_iotadieresis ϊ GREEK SMALL LETTER IOTA WITH DIALYTIKA */ + { 0x07B6, 0x0390 }, /* Greek_iotaaccentdieresis ΐ GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS */ + { 0x07B7, 0x03CC }, /* Greek_omicronaccent ό GREEK SMALL LETTER OMICRON WITH TONOS */ + { 0x07B8, 0x03CD }, /* Greek_upsilonaccent ύ GREEK SMALL LETTER UPSILON WITH TONOS */ + { 0x07B9, 0x03CB }, /* Greek_upsilondieresis ϋ GREEK SMALL LETTER UPSILON WITH DIALYTIKA */ + { 0x07BA, 0x03B0 }, /* Greek_upsilonaccentdieresis ΰ GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS */ + { 0x07BB, 0x03CE }, /* Greek_omegaaccent ώ GREEK SMALL LETTER OMEGA WITH TONOS */ + { 0x07C1, 0x0391 }, /* Greek_ALPHA Α GREEK CAPITAL LETTER ALPHA */ + { 0x07C2, 0x0392 }, /* Greek_BETA Β GREEK CAPITAL LETTER BETA */ + { 0x07C3, 0x0393 }, /* Greek_GAMMA Γ GREEK CAPITAL LETTER GAMMA */ + { 0x07C4, 0x0394 }, /* Greek_DELTA Δ GREEK CAPITAL LETTER DELTA */ + { 0x07C5, 0x0395 }, /* Greek_EPSILON Ε GREEK CAPITAL LETTER EPSILON */ + { 0x07C6, 0x0396 }, /* Greek_ZETA Ζ GREEK CAPITAL LETTER ZETA */ + { 0x07C7, 0x0397 }, /* Greek_ETA Η GREEK CAPITAL LETTER ETA */ + { 0x07C8, 0x0398 }, /* Greek_THETA Θ GREEK CAPITAL LETTER THETA */ + { 0x07C9, 0x0399 }, /* Greek_IOTA Ι GREEK CAPITAL LETTER IOTA */ + { 0x07CA, 0x039A }, /* Greek_KAPPA Κ GREEK CAPITAL LETTER KAPPA */ + { 0x07CB, 0x039B }, /* Greek_LAMBDA Λ GREEK CAPITAL LETTER LAMDA */ + { 0x07CC, 0x039C }, /* Greek_MU Μ GREEK CAPITAL LETTER MU */ + { 0x07CD, 0x039D }, /* Greek_NU Ν GREEK CAPITAL LETTER NU */ + { 0x07CE, 0x039E }, /* Greek_XI Ξ GREEK CAPITAL LETTER XI */ + { 0x07CF, 0x039F }, /* Greek_OMICRON Ο GREEK CAPITAL LETTER OMICRON */ + { 0x07D0, 0x03A0 }, /* Greek_PI Π GREEK CAPITAL LETTER PI */ + { 0x07D1, 0x03A1 }, /* Greek_RHO Ρ GREEK CAPITAL LETTER RHO */ + { 0x07D2, 0x03A3 }, /* Greek_SIGMA Σ GREEK CAPITAL LETTER SIGMA */ + { 0x07D4, 0x03A4 }, /* Greek_TAU Τ GREEK CAPITAL LETTER TAU */ + { 0x07D5, 0x03A5 }, /* Greek_UPSILON Υ GREEK CAPITAL LETTER UPSILON */ + { 0x07D6, 0x03A6 }, /* Greek_PHI Φ GREEK CAPITAL LETTER PHI */ + { 0x07D7, 0x03A7 }, /* Greek_CHI Χ GREEK CAPITAL LETTER CHI */ + { 0x07D8, 0x03A8 }, /* Greek_PSI Ψ GREEK CAPITAL LETTER PSI */ + { 0x07D9, 0x03A9 }, /* Greek_OMEGA Ω GREEK CAPITAL LETTER OMEGA */ + { 0x07E1, 0x03B1 }, /* Greek_alpha α GREEK SMALL LETTER ALPHA */ + { 0x07E2, 0x03B2 }, /* Greek_beta β GREEK SMALL LETTER BETA */ + { 0x07E3, 0x03B3 }, /* Greek_gamma γ GREEK SMALL LETTER GAMMA */ + { 0x07E4, 0x03B4 }, /* Greek_delta δ GREEK SMALL LETTER DELTA */ + { 0x07E5, 0x03B5 }, /* Greek_epsilon ε GREEK SMALL LETTER EPSILON */ + { 0x07E6, 0x03B6 }, /* Greek_zeta ζ GREEK SMALL LETTER ZETA */ + { 0x07E7, 0x03B7 }, /* Greek_eta η GREEK SMALL LETTER ETA */ + { 0x07E8, 0x03B8 }, /* Greek_theta θ GREEK SMALL LETTER THETA */ + { 0x07E9, 0x03B9 }, /* Greek_iota ι GREEK SMALL LETTER IOTA */ + { 0x07EA, 0x03BA }, /* Greek_kappa κ GREEK SMALL LETTER KAPPA */ + { 0x07EB, 0x03BB }, /* Greek_lambda λ GREEK SMALL LETTER LAMDA */ + { 0x07EC, 0x03BC }, /* Greek_mu μ GREEK SMALL LETTER MU */ + { 0x07ED, 0x03BD }, /* Greek_nu ν GREEK SMALL LETTER NU */ + { 0x07EE, 0x03BE }, /* Greek_xi ξ GREEK SMALL LETTER XI */ + { 0x07EF, 0x03BF }, /* Greek_omicron ο GREEK SMALL LETTER OMICRON */ + { 0x07F0, 0x03C0 }, /* Greek_pi π GREEK SMALL LETTER PI */ + { 0x07F1, 0x03C1 }, /* Greek_rho ρ GREEK SMALL LETTER RHO */ + { 0x07F2, 0x03C3 }, /* Greek_sigma σ GREEK SMALL LETTER SIGMA */ + { 0x07F3, 0x03C2 }, /* Greek_finalsmallsigma ς GREEK SMALL LETTER FINAL SIGMA */ + { 0x07F4, 0x03C4 }, /* Greek_tau τ GREEK SMALL LETTER TAU */ + { 0x07F5, 0x03C5 }, /* Greek_upsilon υ GREEK SMALL LETTER UPSILON */ + { 0x07F6, 0x03C6 }, /* Greek_phi φ GREEK SMALL LETTER PHI */ + { 0x07F7, 0x03C7 }, /* Greek_chi χ GREEK SMALL LETTER CHI */ + { 0x07F8, 0x03C8 }, /* Greek_psi ψ GREEK SMALL LETTER PSI */ + { 0x07F9, 0x03C9 }, /* Greek_omega ω GREEK SMALL LETTER OMEGA */ + { 0x08A1, 0x23B7 }, /* leftradical ⎷ ??? */ + { 0x08A2, 0x250C }, /* topleftradical ┌ BOX DRAWINGS LIGHT DOWN AND RIGHT */ + { 0x08A3, 0x2500 }, /* horizconnector ─ BOX DRAWINGS LIGHT HORIZONTAL */ + { 0x08A4, 0x2320 }, /* topintegral ⌠ TOP HALF INTEGRAL */ + { 0x08A5, 0x2321 }, /* botintegral ⌡ BOTTOM HALF INTEGRAL */ + { 0x08A6, 0x2502 }, /* vertconnector │ BOX DRAWINGS LIGHT VERTICAL */ + { 0x08A7, 0x23A1 }, /* topleftsqbracket ⎡ ??? */ + { 0x08A8, 0x23A3 }, /* botleftsqbracket ⎣ ??? */ + { 0x08A9, 0x23A4 }, /* toprightsqbracket ⎤ ??? */ + { 0x08AA, 0x23A6 }, /* botrightsqbracket ⎦ ??? */ + { 0x08AB, 0x239B }, /* topleftparens ⎛ ??? */ + { 0x08AC, 0x239D }, /* botleftparens ⎝ ??? */ + { 0x08AD, 0x239E }, /* toprightparens ⎞ ??? */ + { 0x08AE, 0x23A0 }, /* botrightparens ⎠ ??? */ + { 0x08AF, 0x23A8 }, /* leftmiddlecurlybrace ⎨ ??? */ + { 0x08B0, 0x23AC }, /* rightmiddlecurlybrace ⎬ ??? */ +/* 0x08B1 topleftsummation ? ??? */ +/* 0x08B2 botleftsummation ? ??? */ +/* 0x08B3 topvertsummationconnector ? ??? */ +/* 0x08B4 botvertsummationconnector ? ??? */ +/* 0x08B5 toprightsummation ? ??? */ +/* 0x08B6 botrightsummation ? ??? */ +/* 0x08B7 rightmiddlesummation ? ??? */ + { 0x08BC, 0x2264 }, /* lessthanequal ≤ LESS-THAN OR EQUAL TO */ + { 0x08BD, 0x2260 }, /* notequal ≠ NOT EQUAL TO */ + { 0x08BE, 0x2265 }, /* greaterthanequal ≥ GREATER-THAN OR EQUAL TO */ + { 0x08BF, 0x222B }, /* integral ∫ INTEGRAL */ + { 0x08C0, 0x2234 }, /* therefore ∴ THEREFORE */ + { 0x08C1, 0x221D }, /* variation ∝ PROPORTIONAL TO */ + { 0x08C2, 0x221E }, /* infinity ∞ INFINITY */ + { 0x08C5, 0x2207 }, /* nabla ∇ NABLA */ + { 0x08C8, 0x223C }, /* approximate ∼ TILDE OPERATOR */ + { 0x08C9, 0x2243 }, /* similarequal ≃ ASYMPTOTICALLY EQUAL TO */ + { 0x08CD, 0x21D4 }, /* ifonlyif ⇔ LEFT RIGHT DOUBLE ARROW */ + { 0x08CE, 0x21D2 }, /* implies ⇒ RIGHTWARDS DOUBLE ARROW */ + { 0x08CF, 0x2261 }, /* identical ≡ IDENTICAL TO */ + { 0x08D6, 0x221A }, /* radical √ SQUARE ROOT */ + { 0x08DA, 0x2282 }, /* includedin ⊂ SUBSET OF */ + { 0x08DB, 0x2283 }, /* includes ⊃ SUPERSET OF */ + { 0x08DC, 0x2229 }, /* intersection ∩ INTERSECTION */ + { 0x08DD, 0x222A }, /* union ∪ UNION */ + { 0x08DE, 0x2227 }, /* logicaland ∧ LOGICAL AND */ + { 0x08DF, 0x2228 }, /* logicalor ∨ LOGICAL OR */ + { 0x08EF, 0x2202 }, /* partialderivative ∂ PARTIAL DIFFERENTIAL */ + { 0x08F6, 0x0192 }, /* function ƒ LATIN SMALL LETTER F WITH HOOK */ + { 0x08FB, 0x2190 }, /* leftarrow ← LEFTWARDS ARROW */ + { 0x08FC, 0x2191 }, /* uparrow ↑ UPWARDS ARROW */ + { 0x08FD, 0x2192 }, /* rightarrow → RIGHTWARDS ARROW */ + { 0x08FE, 0x2193 }, /* downarrow ↓ DOWNWARDS ARROW */ +/* 0x09DF blank ? ??? */ + { 0x09E0, 0x25C6 }, /* soliddiamond ◆ BLACK DIAMOND */ + { 0x09E1, 0x2592 }, /* checkerboard ▒ MEDIUM SHADE */ + { 0x09E2, 0x2409 }, /* ht ␉ SYMBOL FOR HORIZONTAL TABULATION */ + { 0x09E3, 0x240C }, /* ff ␌ SYMBOL FOR FORM FEED */ + { 0x09E4, 0x240D }, /* cr ␍ SYMBOL FOR CARRIAGE RETURN */ + { 0x09E5, 0x240A }, /* lf ␊ SYMBOL FOR LINE FEED */ + { 0x09E8, 0x2424 }, /* nl ␤ SYMBOL FOR NEWLINE */ + { 0x09E9, 0x240B }, /* vt ␋ SYMBOL FOR VERTICAL TABULATION */ + { 0x09EA, 0x2518 }, /* lowrightcorner ┘ BOX DRAWINGS LIGHT UP AND LEFT */ + { 0x09EB, 0x2510 }, /* uprightcorner ┐ BOX DRAWINGS LIGHT DOWN AND LEFT */ + { 0x09EC, 0x250C }, /* upleftcorner ┌ BOX DRAWINGS LIGHT DOWN AND RIGHT */ + { 0x09ED, 0x2514 }, /* lowleftcorner └ BOX DRAWINGS LIGHT UP AND RIGHT */ + { 0x09EE, 0x253C }, /* crossinglines ┼ BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL */ + { 0x09EF, 0x23BA }, /* horizlinescan1 ⎺ HORIZONTAL SCAN LINE-1 (Unicode 3.2 draft) */ + { 0x09F0, 0x23BB }, /* horizlinescan3 ⎻ HORIZONTAL SCAN LINE-3 (Unicode 3.2 draft) */ + { 0x09F1, 0x2500 }, /* horizlinescan5 ─ BOX DRAWINGS LIGHT HORIZONTAL */ + { 0x09F2, 0x23BC }, /* horizlinescan7 ⎼ HORIZONTAL SCAN LINE-7 (Unicode 3.2 draft) */ + { 0x09F3, 0x23BD }, /* horizlinescan9 ⎽ HORIZONTAL SCAN LINE-9 (Unicode 3.2 draft) */ + { 0x09F4, 0x251C }, /* leftt ├ BOX DRAWINGS LIGHT VERTICAL AND RIGHT */ + { 0x09F5, 0x2524 }, /* rightt ┤ BOX DRAWINGS LIGHT VERTICAL AND LEFT */ + { 0x09F6, 0x2534 }, /* bott ┴ BOX DRAWINGS LIGHT UP AND HORIZONTAL */ + { 0x09F7, 0x252C }, /* topt ┬ BOX DRAWINGS LIGHT DOWN AND HORIZONTAL */ + { 0x09F8, 0x2502 }, /* vertbar │ BOX DRAWINGS LIGHT VERTICAL */ + { 0x0AA1, 0x2003 }, /* emspace   EM SPACE */ + { 0x0AA2, 0x2002 }, /* enspace   EN SPACE */ + { 0x0AA3, 0x2004 }, /* em3space   THREE-PER-EM SPACE */ + { 0x0AA4, 0x2005 }, /* em4space   FOUR-PER-EM SPACE */ + { 0x0AA5, 0x2007 }, /* digitspace   FIGURE SPACE */ + { 0x0AA6, 0x2008 }, /* punctspace   PUNCTUATION SPACE */ + { 0x0AA7, 0x2009 }, /* thinspace   THIN SPACE */ + { 0x0AA8, 0x200A }, /* hairspace   HAIR SPACE */ + { 0x0AA9, 0x2014 }, /* emdash — EM DASH */ + { 0x0AAA, 0x2013 }, /* endash – EN DASH */ +/* 0x0AAC signifblank ? ??? */ + { 0x0AAE, 0x2026 }, /* ellipsis … HORIZONTAL ELLIPSIS */ + { 0x0AAF, 0x2025 }, /* doubbaselinedot ‥ TWO DOT LEADER */ + { 0x0AB0, 0x2153 }, /* onethird ⅓ VULGAR FRACTION ONE THIRD */ + { 0x0AB1, 0x2154 }, /* twothirds ⅔ VULGAR FRACTION TWO THIRDS */ + { 0x0AB2, 0x2155 }, /* onefifth ⅕ VULGAR FRACTION ONE FIFTH */ + { 0x0AB3, 0x2156 }, /* twofifths ⅖ VULGAR FRACTION TWO FIFTHS */ + { 0x0AB4, 0x2157 }, /* threefifths ⅗ VULGAR FRACTION THREE FIFTHS */ + { 0x0AB5, 0x2158 }, /* fourfifths ⅘ VULGAR FRACTION FOUR FIFTHS */ + { 0x0AB6, 0x2159 }, /* onesixth ⅙ VULGAR FRACTION ONE SIXTH */ + { 0x0AB7, 0x215A }, /* fivesixths ⅚ VULGAR FRACTION FIVE SIXTHS */ + { 0x0AB8, 0x2105 }, /* careof ℅ CARE OF */ + { 0x0ABB, 0x2012 }, /* figdash ‒ FIGURE DASH */ + { 0x0ABC, 0x2329 }, /* leftanglebracket 〈 LEFT-POINTING ANGLE BRACKET */ +/* 0x0ABD decimalpoint ? ??? */ + { 0x0ABE, 0x232A }, /* rightanglebracket 〉 RIGHT-POINTING ANGLE BRACKET */ +/* 0x0ABF marker ? ??? */ + { 0x0AC3, 0x215B }, /* oneeighth ⅛ VULGAR FRACTION ONE EIGHTH */ + { 0x0AC4, 0x215C }, /* threeeighths ⅜ VULGAR FRACTION THREE EIGHTHS */ + { 0x0AC5, 0x215D }, /* fiveeighths ⅝ VULGAR FRACTION FIVE EIGHTHS */ + { 0x0AC6, 0x215E }, /* seveneighths ⅞ VULGAR FRACTION SEVEN EIGHTHS */ + { 0x0AC9, 0x2122 }, /* trademark ™ TRADE MARK SIGN */ + { 0x0ACA, 0x2613 }, /* signaturemark ☓ SALTIRE */ +/* 0x0ACB trademarkincircle ? ??? */ + { 0x0ACC, 0x25C1 }, /* leftopentriangle ◁ WHITE LEFT-POINTING TRIANGLE */ + { 0x0ACD, 0x25B7 }, /* rightopentriangle ▷ WHITE RIGHT-POINTING TRIANGLE */ + { 0x0ACE, 0x25CB }, /* emopencircle ○ WHITE CIRCLE */ + { 0x0ACF, 0x25AF }, /* emopenrectangle ▯ WHITE VERTICAL RECTANGLE */ + { 0x0AD0, 0x2018 }, /* leftsinglequotemark ‘ LEFT SINGLE QUOTATION MARK */ + { 0x0AD1, 0x2019 }, /* rightsinglequotemark ’ RIGHT SINGLE QUOTATION MARK */ + { 0x0AD2, 0x201C }, /* leftdoublequotemark “ LEFT DOUBLE QUOTATION MARK */ + { 0x0AD3, 0x201D }, /* rightdoublequotemark ” RIGHT DOUBLE QUOTATION MARK */ + { 0x0AD4, 0x211E }, /* prescription ℞ PRESCRIPTION TAKE */ + { 0x0AD6, 0x2032 }, /* minutes ′ PRIME */ + { 0x0AD7, 0x2033 }, /* seconds ″ DOUBLE PRIME */ + { 0x0AD9, 0x271D }, /* latincross ✝ LATIN CROSS */ +/* 0x0ADA hexagram ? ??? */ + { 0x0ADB, 0x25AC }, /* filledrectbullet ▬ BLACK RECTANGLE */ + { 0x0ADC, 0x25C0 }, /* filledlefttribullet ◀ BLACK LEFT-POINTING TRIANGLE */ + { 0x0ADD, 0x25B6 }, /* filledrighttribullet ▶ BLACK RIGHT-POINTING TRIANGLE */ + { 0x0ADE, 0x25CF }, /* emfilledcircle ● BLACK CIRCLE */ + { 0x0ADF, 0x25AE }, /* emfilledrect ▮ BLACK VERTICAL RECTANGLE */ + { 0x0AE0, 0x25E6 }, /* enopencircbullet ◦ WHITE BULLET */ + { 0x0AE1, 0x25AB }, /* enopensquarebullet ▫ WHITE SMALL SQUARE */ + { 0x0AE2, 0x25AD }, /* openrectbullet ▭ WHITE RECTANGLE */ + { 0x0AE3, 0x25B3 }, /* opentribulletup △ WHITE UP-POINTING TRIANGLE */ + { 0x0AE4, 0x25BD }, /* opentribulletdown ▽ WHITE DOWN-POINTING TRIANGLE */ + { 0x0AE5, 0x2606 }, /* openstar ☆ WHITE STAR */ + { 0x0AE6, 0x2022 }, /* enfilledcircbullet • BULLET */ + { 0x0AE7, 0x25AA }, /* enfilledsqbullet ▪ BLACK SMALL SQUARE */ + { 0x0AE8, 0x25B2 }, /* filledtribulletup ▲ BLACK UP-POINTING TRIANGLE */ + { 0x0AE9, 0x25BC }, /* filledtribulletdown ▼ BLACK DOWN-POINTING TRIANGLE */ + { 0x0AEA, 0x261C }, /* leftpointer ☜ WHITE LEFT POINTING INDEX */ + { 0x0AEB, 0x261E }, /* rightpointer ☞ WHITE RIGHT POINTING INDEX */ + { 0x0AEC, 0x2663 }, /* club ♣ BLACK CLUB SUIT */ + { 0x0AED, 0x2666 }, /* diamond ♦ BLACK DIAMOND SUIT */ + { 0x0AEE, 0x2665 }, /* heart ♥ BLACK HEART SUIT */ + { 0x0AF0, 0x2720 }, /* maltesecross ✠ MALTESE CROSS */ + { 0x0AF1, 0x2020 }, /* dagger † DAGGER */ + { 0x0AF2, 0x2021 }, /* doubledagger ‡ DOUBLE DAGGER */ + { 0x0AF3, 0x2713 }, /* checkmark ✓ CHECK MARK */ + { 0x0AF4, 0x2717 }, /* ballotcross ✗ BALLOT X */ + { 0x0AF5, 0x266F }, /* musicalsharp ♯ MUSIC SHARP SIGN */ + { 0x0AF6, 0x266D }, /* musicalflat ♭ MUSIC FLAT SIGN */ + { 0x0AF7, 0x2642 }, /* malesymbol ♂ MALE SIGN */ + { 0x0AF8, 0x2640 }, /* femalesymbol ♀ FEMALE SIGN */ + { 0x0AF9, 0x260E }, /* telephone ☎ BLACK TELEPHONE */ + { 0x0AFA, 0x2315 }, /* telephonerecorder ⌕ TELEPHONE RECORDER */ + { 0x0AFB, 0x2117 }, /* phonographcopyright ℗ SOUND RECORDING COPYRIGHT */ + { 0x0AFC, 0x2038 }, /* caret ‸ CARET */ + { 0x0AFD, 0x201A }, /* singlelowquotemark ‚ SINGLE LOW-9 QUOTATION MARK */ + { 0x0AFE, 0x201E }, /* doublelowquotemark „ DOUBLE LOW-9 QUOTATION MARK */ +/* 0x0AFF cursor ? ??? */ + { 0x0BA3, 0x003C }, /* leftcaret < LESS-THAN SIGN */ + { 0x0BA6, 0x003E }, /* rightcaret > GREATER-THAN SIGN */ + { 0x0BA8, 0x2228 }, /* downcaret ∨ LOGICAL OR */ + { 0x0BA9, 0x2227 }, /* upcaret ∧ LOGICAL AND */ + { 0x0BC0, 0x00AF }, /* overbar ¯ MACRON */ + { 0x0BC2, 0x22A5 }, /* downtack ⊥ UP TACK */ + { 0x0BC3, 0x2229 }, /* upshoe ∩ INTERSECTION */ + { 0x0BC4, 0x230A }, /* downstile ⌊ LEFT FLOOR */ + { 0x0BC6, 0x005F }, /* underbar _ LOW LINE */ + { 0x0BCA, 0x2218 }, /* jot ∘ RING OPERATOR */ + { 0x0BCC, 0x2395 }, /* quad ⎕ APL FUNCTIONAL SYMBOL QUAD */ + { 0x0BCE, 0x22A4 }, /* uptack ⊤ DOWN TACK */ + { 0x0BCF, 0x25CB }, /* circle ○ WHITE CIRCLE */ + { 0x0BD3, 0x2308 }, /* upstile ⌈ LEFT CEILING */ + { 0x0BD6, 0x222A }, /* downshoe ∪ UNION */ + { 0x0BD8, 0x2283 }, /* rightshoe ⊃ SUPERSET OF */ + { 0x0BDA, 0x2282 }, /* leftshoe ⊂ SUBSET OF */ + { 0x0BDC, 0x22A2 }, /* lefttack ⊢ RIGHT TACK */ + { 0x0BFC, 0x22A3 }, /* righttack ⊣ LEFT TACK */ + { 0x0CDF, 0x2017 }, /* hebrew_doublelowline ‗ DOUBLE LOW LINE */ + { 0x0CE0, 0x05D0 }, /* hebrew_aleph א HEBREW LETTER ALEF */ + { 0x0CE1, 0x05D1 }, /* hebrew_bet ב HEBREW LETTER BET */ + { 0x0CE2, 0x05D2 }, /* hebrew_gimel ג HEBREW LETTER GIMEL */ + { 0x0CE3, 0x05D3 }, /* hebrew_dalet ד HEBREW LETTER DALET */ + { 0x0CE4, 0x05D4 }, /* hebrew_he ה HEBREW LETTER HE */ + { 0x0CE5, 0x05D5 }, /* hebrew_waw ו HEBREW LETTER VAV */ + { 0x0CE6, 0x05D6 }, /* hebrew_zain ז HEBREW LETTER ZAYIN */ + { 0x0CE7, 0x05D7 }, /* hebrew_chet ח HEBREW LETTER HET */ + { 0x0CE8, 0x05D8 }, /* hebrew_tet ט HEBREW LETTER TET */ + { 0x0CE9, 0x05D9 }, /* hebrew_yod י HEBREW LETTER YOD */ + { 0x0CEA, 0x05DA }, /* hebrew_finalkaph ך HEBREW LETTER FINAL KAF */ + { 0x0CEB, 0x05DB }, /* hebrew_kaph כ HEBREW LETTER KAF */ + { 0x0CEC, 0x05DC }, /* hebrew_lamed ל HEBREW LETTER LAMED */ + { 0x0CED, 0x05DD }, /* hebrew_finalmem ם HEBREW LETTER FINAL MEM */ + { 0x0CEE, 0x05DE }, /* hebrew_mem מ HEBREW LETTER MEM */ + { 0x0CEF, 0x05DF }, /* hebrew_finalnun ן HEBREW LETTER FINAL NUN */ + { 0x0CF0, 0x05E0 }, /* hebrew_nun נ HEBREW LETTER NUN */ + { 0x0CF1, 0x05E1 }, /* hebrew_samech ס HEBREW LETTER SAMEKH */ + { 0x0CF2, 0x05E2 }, /* hebrew_ayin ע HEBREW LETTER AYIN */ + { 0x0CF3, 0x05E3 }, /* hebrew_finalpe ף HEBREW LETTER FINAL PE */ + { 0x0CF4, 0x05E4 }, /* hebrew_pe פ HEBREW LETTER PE */ + { 0x0CF5, 0x05E5 }, /* hebrew_finalzade ץ HEBREW LETTER FINAL TSADI */ + { 0x0CF6, 0x05E6 }, /* hebrew_zade צ HEBREW LETTER TSADI */ + { 0x0CF7, 0x05E7 }, /* hebrew_qoph ק HEBREW LETTER QOF */ + { 0x0CF8, 0x05E8 }, /* hebrew_resh ר HEBREW LETTER RESH */ + { 0x0CF9, 0x05E9 }, /* hebrew_shin ש HEBREW LETTER SHIN */ + { 0x0CFA, 0x05EA }, /* hebrew_taw ת HEBREW LETTER TAV */ + { 0x0DA1, 0x0E01 }, /* Thai_kokai ก THAI CHARACTER KO KAI */ + { 0x0DA2, 0x0E02 }, /* Thai_khokhai ข THAI CHARACTER KHO KHAI */ + { 0x0DA3, 0x0E03 }, /* Thai_khokhuat ฃ THAI CHARACTER KHO KHUAT */ + { 0x0DA4, 0x0E04 }, /* Thai_khokhwai ค THAI CHARACTER KHO KHWAI */ + { 0x0DA5, 0x0E05 }, /* Thai_khokhon ฅ THAI CHARACTER KHO KHON */ + { 0x0DA6, 0x0E06 }, /* Thai_khorakhang ฆ THAI CHARACTER KHO RAKHANG */ + { 0x0DA7, 0x0E07 }, /* Thai_ngongu ง THAI CHARACTER NGO NGU */ + { 0x0DA8, 0x0E08 }, /* Thai_chochan จ THAI CHARACTER CHO CHAN */ + { 0x0DA9, 0x0E09 }, /* Thai_choching ฉ THAI CHARACTER CHO CHING */ + { 0x0DAA, 0x0E0A }, /* Thai_chochang ช THAI CHARACTER CHO CHANG */ + { 0x0DAB, 0x0E0B }, /* Thai_soso ซ THAI CHARACTER SO SO */ + { 0x0DAC, 0x0E0C }, /* Thai_chochoe ฌ THAI CHARACTER CHO CHOE */ + { 0x0DAD, 0x0E0D }, /* Thai_yoying ญ THAI CHARACTER YO YING */ + { 0x0DAE, 0x0E0E }, /* Thai_dochada ฎ THAI CHARACTER DO CHADA */ + { 0x0DAF, 0x0E0F }, /* Thai_topatak ฏ THAI CHARACTER TO PATAK */ + { 0x0DB0, 0x0E10 }, /* Thai_thothan ฐ THAI CHARACTER THO THAN */ + { 0x0DB1, 0x0E11 }, /* Thai_thonangmontho ฑ THAI CHARACTER THO NANGMONTHO */ + { 0x0DB2, 0x0E12 }, /* Thai_thophuthao ฒ THAI CHARACTER THO PHUTHAO */ + { 0x0DB3, 0x0E13 }, /* Thai_nonen ณ THAI CHARACTER NO NEN */ + { 0x0DB4, 0x0E14 }, /* Thai_dodek ด THAI CHARACTER DO DEK */ + { 0x0DB5, 0x0E15 }, /* Thai_totao ต THAI CHARACTER TO TAO */ + { 0x0DB6, 0x0E16 }, /* Thai_thothung ถ THAI CHARACTER THO THUNG */ + { 0x0DB7, 0x0E17 }, /* Thai_thothahan ท THAI CHARACTER THO THAHAN */ + { 0x0DB8, 0x0E18 }, /* Thai_thothong ธ THAI CHARACTER THO THONG */ + { 0x0DB9, 0x0E19 }, /* Thai_nonu น THAI CHARACTER NO NU */ + { 0x0DBA, 0x0E1A }, /* Thai_bobaimai บ THAI CHARACTER BO BAIMAI */ + { 0x0DBB, 0x0E1B }, /* Thai_popla ป THAI CHARACTER PO PLA */ + { 0x0DBC, 0x0E1C }, /* Thai_phophung ผ THAI CHARACTER PHO PHUNG */ + { 0x0DBD, 0x0E1D }, /* Thai_fofa ฝ THAI CHARACTER FO FA */ + { 0x0DBE, 0x0E1E }, /* Thai_phophan พ THAI CHARACTER PHO PHAN */ + { 0x0DBF, 0x0E1F }, /* Thai_fofan ฟ THAI CHARACTER FO FAN */ + { 0x0DC0, 0x0E20 }, /* Thai_phosamphao ภ THAI CHARACTER PHO SAMPHAO */ + { 0x0DC1, 0x0E21 }, /* Thai_moma ม THAI CHARACTER MO MA */ + { 0x0DC2, 0x0E22 }, /* Thai_yoyak ย THAI CHARACTER YO YAK */ + { 0x0DC3, 0x0E23 }, /* Thai_rorua ร THAI CHARACTER RO RUA */ + { 0x0DC4, 0x0E24 }, /* Thai_ru ฤ THAI CHARACTER RU */ + { 0x0DC5, 0x0E25 }, /* Thai_loling ล THAI CHARACTER LO LING */ + { 0x0DC6, 0x0E26 }, /* Thai_lu ฦ THAI CHARACTER LU */ + { 0x0DC7, 0x0E27 }, /* Thai_wowaen ว THAI CHARACTER WO WAEN */ + { 0x0DC8, 0x0E28 }, /* Thai_sosala ศ THAI CHARACTER SO SALA */ + { 0x0DC9, 0x0E29 }, /* Thai_sorusi ษ THAI CHARACTER SO RUSI */ + { 0x0DCA, 0x0E2A }, /* Thai_sosua ส THAI CHARACTER SO SUA */ + { 0x0DCB, 0x0E2B }, /* Thai_hohip ห THAI CHARACTER HO HIP */ + { 0x0DCC, 0x0E2C }, /* Thai_lochula ฬ THAI CHARACTER LO CHULA */ + { 0x0DCD, 0x0E2D }, /* Thai_oang อ THAI CHARACTER O ANG */ + { 0x0DCE, 0x0E2E }, /* Thai_honokhuk ฮ THAI CHARACTER HO NOKHUK */ + { 0x0DCF, 0x0E2F }, /* Thai_paiyannoi ฯ THAI CHARACTER PAIYANNOI */ + { 0x0DD0, 0x0E30 }, /* Thai_saraa ะ THAI CHARACTER SARA A */ + { 0x0DD1, 0x0E31 }, /* Thai_maihanakat ั THAI CHARACTER MAI HAN-AKAT */ + { 0x0DD2, 0x0E32 }, /* Thai_saraaa า THAI CHARACTER SARA AA */ + { 0x0DD3, 0x0E33 }, /* Thai_saraam ำ THAI CHARACTER SARA AM */ + { 0x0DD4, 0x0E34 }, /* Thai_sarai ิ THAI CHARACTER SARA I */ + { 0x0DD5, 0x0E35 }, /* Thai_saraii ี THAI CHARACTER SARA II */ + { 0x0DD6, 0x0E36 }, /* Thai_saraue ึ THAI CHARACTER SARA UE */ + { 0x0DD7, 0x0E37 }, /* Thai_sarauee ื THAI CHARACTER SARA UEE */ + { 0x0DD8, 0x0E38 }, /* Thai_sarau ุ THAI CHARACTER SARA U */ + { 0x0DD9, 0x0E39 }, /* Thai_sarauu ู THAI CHARACTER SARA UU */ + { 0x0DDA, 0x0E3A }, /* Thai_phinthu ฺ THAI CHARACTER PHINTHU */ +/* 0x0DDE Thai_maihanakat_maitho ? ??? */ + { 0x0DDF, 0x0E3F }, /* Thai_baht ฿ THAI CURRENCY SYMBOL BAHT */ + { 0x0DE0, 0x0E40 }, /* Thai_sarae เ THAI CHARACTER SARA E */ + { 0x0DE1, 0x0E41 }, /* Thai_saraae แ THAI CHARACTER SARA AE */ + { 0x0DE2, 0x0E42 }, /* Thai_sarao โ THAI CHARACTER SARA O */ + { 0x0DE3, 0x0E43 }, /* Thai_saraaimaimuan ใ THAI CHARACTER SARA AI MAIMUAN */ + { 0x0DE4, 0x0E44 }, /* Thai_saraaimaimalai ไ THAI CHARACTER SARA AI MAIMALAI */ + { 0x0DE5, 0x0E45 }, /* Thai_lakkhangyao ๅ THAI CHARACTER LAKKHANGYAO */ + { 0x0DE6, 0x0E46 }, /* Thai_maiyamok ๆ THAI CHARACTER MAIYAMOK */ + { 0x0DE7, 0x0E47 }, /* Thai_maitaikhu ็ THAI CHARACTER MAITAIKHU */ + { 0x0DE8, 0x0E48 }, /* Thai_maiek ่ THAI CHARACTER MAI EK */ + { 0x0DE9, 0x0E49 }, /* Thai_maitho ้ THAI CHARACTER MAI THO */ + { 0x0DEA, 0x0E4A }, /* Thai_maitri ๊ THAI CHARACTER MAI TRI */ + { 0x0DEB, 0x0E4B }, /* Thai_maichattawa ๋ THAI CHARACTER MAI CHATTAWA */ + { 0x0DEC, 0x0E4C }, /* Thai_thanthakhat ์ THAI CHARACTER THANTHAKHAT */ + { 0x0DED, 0x0E4D }, /* Thai_nikhahit ํ THAI CHARACTER NIKHAHIT */ + { 0x0DF0, 0x0E50 }, /* Thai_leksun ๐ THAI DIGIT ZERO */ + { 0x0DF1, 0x0E51 }, /* Thai_leknung ๑ THAI DIGIT ONE */ + { 0x0DF2, 0x0E52 }, /* Thai_leksong ๒ THAI DIGIT TWO */ + { 0x0DF3, 0x0E53 }, /* Thai_leksam ๓ THAI DIGIT THREE */ + { 0x0DF4, 0x0E54 }, /* Thai_leksi ๔ THAI DIGIT FOUR */ + { 0x0DF5, 0x0E55 }, /* Thai_lekha ๕ THAI DIGIT FIVE */ + { 0x0DF6, 0x0E56 }, /* Thai_lekhok ๖ THAI DIGIT SIX */ + { 0x0DF7, 0x0E57 }, /* Thai_lekchet ๗ THAI DIGIT SEVEN */ + { 0x0DF8, 0x0E58 }, /* Thai_lekpaet ๘ THAI DIGIT EIGHT */ + { 0x0DF9, 0x0E59 }, /* Thai_lekkao ๙ THAI DIGIT NINE */ + { 0x0EA1, 0x3131 }, /* Hangul_Kiyeog ㄱ HANGUL LETTER KIYEOK */ + { 0x0EA2, 0x3132 }, /* Hangul_SsangKiyeog ㄲ HANGUL LETTER SSANGKIYEOK */ + { 0x0EA3, 0x3133 }, /* Hangul_KiyeogSios ㄳ HANGUL LETTER KIYEOK-SIOS */ + { 0x0EA4, 0x3134 }, /* Hangul_Nieun ㄴ HANGUL LETTER NIEUN */ + { 0x0EA5, 0x3135 }, /* Hangul_NieunJieuj ㄵ HANGUL LETTER NIEUN-CIEUC */ + { 0x0EA6, 0x3136 }, /* Hangul_NieunHieuh ㄶ HANGUL LETTER NIEUN-HIEUH */ + { 0x0EA7, 0x3137 }, /* Hangul_Dikeud ㄷ HANGUL LETTER TIKEUT */ + { 0x0EA8, 0x3138 }, /* Hangul_SsangDikeud ㄸ HANGUL LETTER SSANGTIKEUT */ + { 0x0EA9, 0x3139 }, /* Hangul_Rieul ㄹ HANGUL LETTER RIEUL */ + { 0x0EAA, 0x313A }, /* Hangul_RieulKiyeog ㄺ HANGUL LETTER RIEUL-KIYEOK */ + { 0x0EAB, 0x313B }, /* Hangul_RieulMieum ㄻ HANGUL LETTER RIEUL-MIEUM */ + { 0x0EAC, 0x313C }, /* Hangul_RieulPieub ㄼ HANGUL LETTER RIEUL-PIEUP */ + { 0x0EAD, 0x313D }, /* Hangul_RieulSios ㄽ HANGUL LETTER RIEUL-SIOS */ + { 0x0EAE, 0x313E }, /* Hangul_RieulTieut ㄾ HANGUL LETTER RIEUL-THIEUTH */ + { 0x0EAF, 0x313F }, /* Hangul_RieulPhieuf ㄿ HANGUL LETTER RIEUL-PHIEUPH */ + { 0x0EB0, 0x3140 }, /* Hangul_RieulHieuh ㅀ HANGUL LETTER RIEUL-HIEUH */ + { 0x0EB1, 0x3141 }, /* Hangul_Mieum ㅁ HANGUL LETTER MIEUM */ + { 0x0EB2, 0x3142 }, /* Hangul_Pieub ㅂ HANGUL LETTER PIEUP */ + { 0x0EB3, 0x3143 }, /* Hangul_SsangPieub ㅃ HANGUL LETTER SSANGPIEUP */ + { 0x0EB4, 0x3144 }, /* Hangul_PieubSios ㅄ HANGUL LETTER PIEUP-SIOS */ + { 0x0EB5, 0x3145 }, /* Hangul_Sios ㅅ HANGUL LETTER SIOS */ + { 0x0EB6, 0x3146 }, /* Hangul_SsangSios ㅆ HANGUL LETTER SSANGSIOS */ + { 0x0EB7, 0x3147 }, /* Hangul_Ieung ㅇ HANGUL LETTER IEUNG */ + { 0x0EB8, 0x3148 }, /* Hangul_Jieuj ㅈ HANGUL LETTER CIEUC */ + { 0x0EB9, 0x3149 }, /* Hangul_SsangJieuj ㅉ HANGUL LETTER SSANGCIEUC */ + { 0x0EBA, 0x314A }, /* Hangul_Cieuc ㅊ HANGUL LETTER CHIEUCH */ + { 0x0EBB, 0x314B }, /* Hangul_Khieuq ㅋ HANGUL LETTER KHIEUKH */ + { 0x0EBC, 0x314C }, /* Hangul_Tieut ㅌ HANGUL LETTER THIEUTH */ + { 0x0EBD, 0x314D }, /* Hangul_Phieuf ㅍ HANGUL LETTER PHIEUPH */ + { 0x0EBE, 0x314E }, /* Hangul_Hieuh ㅎ HANGUL LETTER HIEUH */ + { 0x0EBF, 0x314F }, /* Hangul_A ㅏ HANGUL LETTER A */ + { 0x0EC0, 0x3150 }, /* Hangul_AE ㅐ HANGUL LETTER AE */ + { 0x0EC1, 0x3151 }, /* Hangul_YA ㅑ HANGUL LETTER YA */ + { 0x0EC2, 0x3152 }, /* Hangul_YAE ㅒ HANGUL LETTER YAE */ + { 0x0EC3, 0x3153 }, /* Hangul_EO ㅓ HANGUL LETTER EO */ + { 0x0EC4, 0x3154 }, /* Hangul_E ㅔ HANGUL LETTER E */ + { 0x0EC5, 0x3155 }, /* Hangul_YEO ㅕ HANGUL LETTER YEO */ + { 0x0EC6, 0x3156 }, /* Hangul_YE ㅖ HANGUL LETTER YE */ + { 0x0EC7, 0x3157 }, /* Hangul_O ㅗ HANGUL LETTER O */ + { 0x0EC8, 0x3158 }, /* Hangul_WA ㅘ HANGUL LETTER WA */ + { 0x0EC9, 0x3159 }, /* Hangul_WAE ㅙ HANGUL LETTER WAE */ + { 0x0ECA, 0x315A }, /* Hangul_OE ㅚ HANGUL LETTER OE */ + { 0x0ECB, 0x315B }, /* Hangul_YO ㅛ HANGUL LETTER YO */ + { 0x0ECC, 0x315C }, /* Hangul_U ㅜ HANGUL LETTER U */ + { 0x0ECD, 0x315D }, /* Hangul_WEO ㅝ HANGUL LETTER WEO */ + { 0x0ECE, 0x315E }, /* Hangul_WE ㅞ HANGUL LETTER WE */ + { 0x0ECF, 0x315F }, /* Hangul_WI ㅟ HANGUL LETTER WI */ + { 0x0ED0, 0x3160 }, /* Hangul_YU ㅠ HANGUL LETTER YU */ + { 0x0ED1, 0x3161 }, /* Hangul_EU ㅡ HANGUL LETTER EU */ + { 0x0ED2, 0x3162 }, /* Hangul_YI ㅢ HANGUL LETTER YI */ + { 0x0ED3, 0x3163 }, /* Hangul_I ㅣ HANGUL LETTER I */ + { 0x0ED4, 0x11A8 }, /* Hangul_J_Kiyeog ᆨ HANGUL JONGSEONG KIYEOK */ + { 0x0ED5, 0x11A9 }, /* Hangul_J_SsangKiyeog ᆩ HANGUL JONGSEONG SSANGKIYEOK */ + { 0x0ED6, 0x11AA }, /* Hangul_J_KiyeogSios ᆪ HANGUL JONGSEONG KIYEOK-SIOS */ + { 0x0ED7, 0x11AB }, /* Hangul_J_Nieun ᆫ HANGUL JONGSEONG NIEUN */ + { 0x0ED8, 0x11AC }, /* Hangul_J_NieunJieuj ᆬ HANGUL JONGSEONG NIEUN-CIEUC */ + { 0x0ED9, 0x11AD }, /* Hangul_J_NieunHieuh ᆭ HANGUL JONGSEONG NIEUN-HIEUH */ + { 0x0EDA, 0x11AE }, /* Hangul_J_Dikeud ᆮ HANGUL JONGSEONG TIKEUT */ + { 0x0EDB, 0x11AF }, /* Hangul_J_Rieul ᆯ HANGUL JONGSEONG RIEUL */ + { 0x0EDC, 0x11B0 }, /* Hangul_J_RieulKiyeog ᆰ HANGUL JONGSEONG RIEUL-KIYEOK */ + { 0x0EDD, 0x11B1 }, /* Hangul_J_RieulMieum ᆱ HANGUL JONGSEONG RIEUL-MIEUM */ + { 0x0EDE, 0x11B2 }, /* Hangul_J_RieulPieub ᆲ HANGUL JONGSEONG RIEUL-PIEUP */ + { 0x0EDF, 0x11B3 }, /* Hangul_J_RieulSios ᆳ HANGUL JONGSEONG RIEUL-SIOS */ + { 0x0EE0, 0x11B4 }, /* Hangul_J_RieulTieut ᆴ HANGUL JONGSEONG RIEUL-THIEUTH */ + { 0x0EE1, 0x11B5 }, /* Hangul_J_RieulPhieuf ᆵ HANGUL JONGSEONG RIEUL-PHIEUPH */ + { 0x0EE2, 0x11B6 }, /* Hangul_J_RieulHieuh ᆶ HANGUL JONGSEONG RIEUL-HIEUH */ + { 0x0EE3, 0x11B7 }, /* Hangul_J_Mieum ᆷ HANGUL JONGSEONG MIEUM */ + { 0x0EE4, 0x11B8 }, /* Hangul_J_Pieub ᆸ HANGUL JONGSEONG PIEUP */ + { 0x0EE5, 0x11B9 }, /* Hangul_J_PieubSios ᆹ HANGUL JONGSEONG PIEUP-SIOS */ + { 0x0EE6, 0x11BA }, /* Hangul_J_Sios ᆺ HANGUL JONGSEONG SIOS */ + { 0x0EE7, 0x11BB }, /* Hangul_J_SsangSios ᆻ HANGUL JONGSEONG SSANGSIOS */ + { 0x0EE8, 0x11BC }, /* Hangul_J_Ieung ᆼ HANGUL JONGSEONG IEUNG */ + { 0x0EE9, 0x11BD }, /* Hangul_J_Jieuj ᆽ HANGUL JONGSEONG CIEUC */ + { 0x0EEA, 0x11BE }, /* Hangul_J_Cieuc ᆾ HANGUL JONGSEONG CHIEUCH */ + { 0x0EEB, 0x11BF }, /* Hangul_J_Khieuq ᆿ HANGUL JONGSEONG KHIEUKH */ + { 0x0EEC, 0x11C0 }, /* Hangul_J_Tieut ᇀ HANGUL JONGSEONG THIEUTH */ + { 0x0EED, 0x11C1 }, /* Hangul_J_Phieuf ᇁ HANGUL JONGSEONG PHIEUPH */ + { 0x0EEE, 0x11C2 }, /* Hangul_J_Hieuh ᇂ HANGUL JONGSEONG HIEUH */ + { 0x0EEF, 0x316D }, /* Hangul_RieulYeorinHieuh ㅭ HANGUL LETTER RIEUL-YEORINHIEUH */ + { 0x0EF0, 0x3171 }, /* Hangul_SunkyeongeumMieum ㅱ HANGUL LETTER KAPYEOUNMIEUM */ + { 0x0EF1, 0x3178 }, /* Hangul_SunkyeongeumPieub ㅸ HANGUL LETTER KAPYEOUNPIEUP */ + { 0x0EF2, 0x317F }, /* Hangul_PanSios ㅿ HANGUL LETTER PANSIOS */ + { 0x0EF3, 0x3181 }, /* Hangul_KkogjiDalrinIeung ㆁ HANGUL LETTER YESIEUNG */ + { 0x0EF4, 0x3184 }, /* Hangul_SunkyeongeumPhieuf ㆄ HANGUL LETTER KAPYEOUNPHIEUPH */ + { 0x0EF5, 0x3186 }, /* Hangul_YeorinHieuh ㆆ HANGUL LETTER YEORINHIEUH */ + { 0x0EF6, 0x318D }, /* Hangul_AraeA ㆍ HANGUL LETTER ARAEA */ + { 0x0EF7, 0x318E }, /* Hangul_AraeAE ㆎ HANGUL LETTER ARAEAE */ + { 0x0EF8, 0x11EB }, /* Hangul_J_PanSios ᇫ HANGUL JONGSEONG PANSIOS */ + { 0x0EF9, 0x11F0 }, /* Hangul_J_KkogjiDalrinIeung ᇰ HANGUL JONGSEONG YESIEUNG */ + { 0x0EFA, 0x11F9 }, /* Hangul_J_YeorinHieuh ᇹ HANGUL JONGSEONG YEORINHIEUH */ + { 0x0EFF, 0x20A9 }, /* Korean_Won ₩ WON SIGN */ + { 0x13A4, 0x20AC }, /* Euro € EURO SIGN */ + { 0x13BC, 0x0152 }, /* OE Œ LATIN CAPITAL LIGATURE OE */ + { 0x13BD, 0x0153 }, /* oe œ LATIN SMALL LIGATURE OE */ + { 0x13BE, 0x0178 }, /* Ydiaeresis Ÿ LATIN CAPITAL LETTER Y WITH DIAERESIS */ + { 0x20AC, 0x20AC }, /* EuroSign € EURO SIGN */ +}; + +/*********************************************************************** + * The following function converts ISO 10646-1 (UCS, Unicode) values to + * their corresponding KeySym values. + * + * The UTF-8 -> keysym conversion will hopefully one day be provided by + * Xlib via XmbLookupString() and should ideally not have to be + * done in X applications. But we are not there yet. + * + * Author: Markus G. Kuhn , University of Cambridge, + * June 1999 + * + * Special thanks to Richard Verhoeven for preparing + * an initial draft of the mapping table. + * + * This software is in the public domain. Share and enjoy! + ***********************************************************************/ +KeySym unicode_to_keysym(uint16_t unicode) { + int min = 0; + int max = sizeof(keysym_unicode_table) / sizeof(struct codepair) - 1; + int mid; + + #ifdef XK_LATIN1 + // First check for Latin-1 characters. (1:1 mapping) + if ((unicode >= 0x0020 && unicode <= 0x007E) || + (unicode >= 0x00A0 && unicode <= 0x00FF)) { + return unicode; + } + #endif + + // Binary search the lookup table. + while (max >= min) { + mid = (min + max) / 2; + if (keysym_unicode_table[mid].unicode < unicode) { + min = mid + 1; + } + else if (keysym_unicode_table[mid].unicode > unicode) { + max = mid - 1; + } + else { + // Found it. + return keysym_unicode_table[mid].keysym; + } + } + + // No matching KeySym value found, return UCS2 with bit set. + return unicode | 0x01000000; +} + + +/*********************************************************************** + * The following function converts KeySym values into the corresponding + * ISO 10646-1 (UCS, Unicode) values. + * + * The keysym -> UTF-8 conversion will hopefully one day be provided by + * Xlib via XLookupKeySym and should ideally not have to be done in X + * applications. But we are not there yet. + * + * Author: Markus G. Kuhn , University of Cambridge, + * June 1999 + * + * Special thanks to Richard Verhoeven for preparing + * an initial draft of the mapping table. + * + * This software is in the public domain. Share and enjoy! + ***********************************************************************/ +size_t keysym_to_unicode(KeySym keysym, uint16_t *buffer, size_t size) { + size_t count = 0; + + int min = 0; + int max = sizeof(keysym_unicode_table) / sizeof(struct codepair) - 1; + int mid; + + #ifdef XK_LATIN1 + // First check for Latin-1 characters. (1:1 mapping) + if ((keysym >= 0x0020 && keysym <= 0x007E) + || (keysym >= 0x00A0 && keysym <= 0x00FF)) { + + if (count < size) { + buffer[count++] = keysym; + } + + return count; + } + #endif + + // Also check for directly encoded 24-bit UCS characters. + #if defined(XK_LATIN8) || defined(XK_ARABIC) || defined(XK_CYRILLIC) || \ + defined(XK_ARMENIAN) || defined(XK_GEORGIAN) || defined(XK_CAUCASUS) || \ + defined(XK_VIETNAMESE) || defined(XK_CURRENCY) || \ + defined(XK_MATHEMATICAL) || defined(XK_BRAILLE) || defined(XK_SINHALA) + if ((keysym & 0xFF000000) == 0x01000000) { + if (count < size) { + buffer[count++] = keysym & 0x00FFFFFF; + } + + return count; + } + #endif + + // Binary search in table. + while (max >= min) { + mid = (min + max) / 2; + if (keysym_unicode_table[mid].keysym < keysym) { + min = mid + 1; + } + else if (keysym_unicode_table[mid].keysym > keysym) { + max = mid - 1; + } + else { + // Found it. + if (count < size) { + buffer[count++] = keysym_unicode_table[mid].unicode; + } + + return count; + } + } + + // No matching Unicode value found! + return count; +} + + +/* The following code is based on vncdisplaykeymap.c under the following terms: + * + * Copyright (C) 2008 Anthony Liguori + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 2 as + * published by the Free Software Foundation. + */ +uint16_t keycode_to_scancode(KeyCode keycode) { + uint16_t scancode = VC_UNDEFINED; + + #if defined(USE_EVDEV) && defined(USE_XKB) + // Check to see if evdev is enabled. + if (is_evdev) { + unsigned short evdev_size = sizeof(evdev_scancode_table) / sizeof(evdev_scancode_table[0]); + + // NOTE scancodes < 97 appear to be identical between Evdev and XFree86. + if (keycode < evdev_size) { + // For scancode < 97, a simple scancode - 8 offest could be applied, + // but math is generally slower than memory and we cannot save any + // extra space in the lookup table due to binary padding. + scancode = evdev_scancode_table[keycode][0]; + } + } + else { + // Evdev was disabled, fallback to XFree86. + #endif + unsigned short xfree86_size = sizeof(xfree86_scancode_table) / sizeof(xfree86_scancode_table[0]); + + // NOTE scancodes < 97 appear to be identical between Evdev and XFree86. + if (keycode < xfree86_size) { + // For scancode < 97, a simple scancode - 8 offest could be applied, + // but math is generally slower than memory and we cannot save any + // extra space in the lookup table due to binary padding. + scancode = xfree86_scancode_table[keycode][0]; + } + #if defined(USE_EVDEV) && defined(USE_XKB) + } + #endif + + return scancode; +} + +KeyCode scancode_to_keycode(uint16_t scancode) { + KeyCode keycode = 0x0000; + + #if defined(USE_EVDEV) && defined(USE_XKB) + // Check to see if Evdev is enabled. + if (is_evdev) { + unsigned short evdev_size = sizeof(evdev_scancode_table) / sizeof(evdev_scancode_table[0]); + + // NOTE scancodes < 97 appear to be identical between Evdev and XFree86. + if (scancode < 128) { + // For scancode < 97, a simple scancode + 8 offest could be applied, + // but math is generally slower than memory and we cannot save any + // extra space in the lookup table due to binary padding. + keycode = evdev_scancode_table[scancode][1]; + } + else { + // Offset is the lower order bits + 128 + scancode = (scancode & 0x007F) | 0x80; + + if (scancode < evdev_size) { + keycode = evdev_scancode_table[scancode][1]; + } + } + } + else { + // Evdev was disabled, fallback to XFree86. + #endif + unsigned short xfree86_size = sizeof(xfree86_scancode_table) / sizeof(xfree86_scancode_table[0]); + + // NOTE scancodes < 97 appear to be identical between Evdev and XFree86. + if (scancode < 128) { + // For scancode < 97, a simple scancode + 8 offest could be applied, + // but math is generally slower than memory and we cannot save any + // extra space in the lookup table due to binary padding. + keycode = xfree86_scancode_table[scancode][1]; + } + else { + // Offset: lower order bits + 128 (If no size optimization!) + scancode = (scancode & 0x007F) | 0x80; + + if (scancode < xfree86_size) { + keycode = xfree86_scancode_table[scancode][1]; + } + } + #if defined(USE_EVDEV) && defined(USE_XKB) + } + #endif + + return keycode; +} + +#ifdef USE_XKBCOMMON +struct xkb_state * create_xkb_state(struct xkb_context *context, xcb_connection_t *connection) { + struct xkb_keymap *keymap; + struct xkb_state *state; + + int32_t device_id = xkb_x11_get_core_keyboard_device_id(connection); + if (device_id >= 0) { + keymap = xkb_x11_keymap_new_from_device(context, connection, device_id, XKB_KEYMAP_COMPILE_NO_FLAGS); + state = xkb_x11_state_new_from_device(keymap, connection, device_id); + } + #ifdef USE_XKBFILE + else { + // Evdev fallback, + logger(LOG_LEVEL_WARN, "%s [%u]: Unable to retrieve core keyboard device id! (%d)\n", + __FUNCTION__, __LINE__, device_id); + + keymap = xkb_keymap_new_from_names(context, &xkb_names, XKB_KEYMAP_COMPILE_NO_FLAGS); + state = xkb_state_new(keymap); + } + #endif + + xkb_map_unref(keymap); + return xkb_state_ref(state); +} + +void destroy_xkb_state(struct xkb_state* state) { + xkb_state_unref(state); +} + +size_t keycode_to_unicode(struct xkb_state* state, KeyCode keycode, uint16_t *buffer, size_t length) { + size_t count = 0; + + if (state != NULL) { + uint32_t unicode = xkb_state_key_get_utf32(state, keycode); + + if (unicode <= 0x10FFFF) { + if ((unicode <= 0xD7FF || (unicode >= 0xE000 && unicode <= 0xFFFF)) && length >= 1) { + buffer[0] = unicode; + count = 1; + } + else if (unicode >= 0x10000) { + unsigned int code = (unicode - 0x10000); + buffer[0] = 0xD800 | (code >> 10); + buffer[1] = 0xDC00 | (code & 0x3FF); + count = 2; + } + } + } + + return count; +} +#else +// Faster more flexible alternative to XKeycodeToKeysym... +KeySym keycode_to_keysym(KeyCode keycode, unsigned int modifier_mask) { + KeySym keysym = NoSymbol; + + #ifdef USE_XKB + if (keyboard_map != NULL) { + // Get the range and number of symbols groups bound to the key. + unsigned char info = XkbKeyGroupInfo(keyboard_map, keycode); + unsigned int num_groups = XkbKeyNumGroups(keyboard_map, keycode); + + // Get the group. + unsigned int group = 0x0000; + switch (XkbOutOfRangeGroupAction(info)) { + case XkbRedirectIntoRange: + /* If the RedirectIntoRange flag is set, the four least significant + * bits of the groups wrap control specify the index of a group to + * which all illegal groups correspond. If the specified group is + * also out of range, all illegal groups map to Group1. + */ + group = XkbOutOfRangeGroupInfo(info); + if (group >= num_groups) { + group = 0; + } + break; + + case XkbClampIntoRange: + /* If the ClampIntoRange flag is set, out-of-range groups correspond + * to the nearest legal group. Effective groups larger than the + * highest supported group are mapped to the highest supported group; + * effective groups less than Group1 are mapped to Group1 . For + * example, a key with two groups of symbols uses Group2 type and + * symbols if the global effective group is either Group3 or Group4. + */ + group = num_groups - 1; + break; + + case XkbWrapIntoRange: + /* If neither flag is set, group is wrapped into range using integer + * modulus. For example, a key with two groups of symbols for which + * groups wrap uses Group1 symbols if the global effective group is + * Group3 or Group2 symbols if the global effective group is Group4. + */ + default: + if (num_groups != 0) { + group %= num_groups; + } + break; + } + + XkbKeyTypePtr key_type = XkbKeyKeyType(keyboard_map, keycode, group); + unsigned int active_mods = modifier_mask & key_type->mods.mask; + + int i, level = 0; + for (i = 0; i < key_type->map_count; i++) { + if (key_type->map[i].active && key_type->map[i].mods.mask == active_mods) { + level = key_type->map[i].level; + } + } + + keysym = XkbKeySymEntry(keyboard_map, keycode, level, group); + } + #else + if (keyboard_map != NULL) { + if (modifier_mask & Mod2Mask && + ((keyboard_map[keycode *keysym_per_keycode + 1] >= 0xFF80 && keyboard_map[keycode *keysym_per_keycode + 1] <= 0xFFBD) || + (keyboard_map[keycode *keysym_per_keycode + 1] >= 0x11000000 && keyboard_map[keycode *keysym_per_keycode + 1] <= 0x1100FFFF)) + ) { + + /* If the numlock modifier is on and the second KeySym is a keypad + * KeySym. In this case, if the Shift modifier is on, or if the + * Lock modifier is on and is interpreted as ShiftLock, then the + * first KeySym is used, otherwise the second KeySym is used. + * + * The standard KeySyms with the prefix ``XK_KP_'' in their name are + * called keypad KeySyms; these are KeySyms with numeric value in + * the hexadecimal range 0xFF80 to 0xFFBD inclusive. In addition, + * vendor-specific KeySyms in the hexadecimal range 0x11000000 to + * 0x1100FFFF are also keypad KeySyms. + */ + + + /* The numlock modifier is on and the second KeySym is a keypad + * KeySym. In this case, if the Shift modifier is on, or if the + * Lock modifier is on and is interpreted as ShiftLock, then the + * first KeySym is used, otherwise the second KeySym is used. + */ + if (modifier_mask & ShiftMask || (modifier_mask & LockMask && is_shift_lock)) { + // i = 0 + keysym = keyboard_map[keycode *keysym_per_keycode]; + } + else { + // i = 1 + keysym = keyboard_map[keycode *keysym_per_keycode + 1]; + } + } + else if (modifier_mask ^ ShiftMask && modifier_mask ^ LockMask) { + /* The Shift and Lock modifiers are both off. In this case, + * the first KeySym is used. + */ + // index = 0 + keysym = keyboard_map[keycode *keysym_per_keycode]; + } + else if (modifier_mask ^ ShiftMask && modifier_mask & LockMask && is_caps_lock) { + /* The Shift modifier is off, and the Lock modifier is on + * and is interpreted as CapsLock. In this case, the first + * KeySym is used, but if that KeySym is lowercase + * alphabetic, then the corresponding uppercase KeySym is + * used instead. + */ + // index = 0; + keysym = keyboard_map[keycode *keysym_per_keycode]; + + if (keysym >= 'a' && keysym <= 'z') { + // keysym is an alpha char. + KeySym lower_keysym, upper_keysym; + XConvertCase(keysym, &lower_keysym, &upper_keysym); + keysym = upper_keysym; + } + } + else if (modifier_mask & ShiftMask && modifier_mask & LockMask && is_caps_lock) { + /* The Shift modifier is on, and the Lock modifier is on and + * is interpreted as CapsLock. In this case, the second + * KeySym is used, but if that KeySym is lowercase + * alphabetic, then the corresponding uppercase KeySym is + * used instead. + */ + // index = 1 + keysym = keyboard_map[keycode *keysym_per_keycode + 1]; + + if (keysym >= 'A' && keysym <= 'Z') { + // keysym is an alpha char. + KeySym lower_keysym, upper_keysym; + XConvertCase(keysym, &lower_keysym, &upper_keysym); + keysym = lower_keysym; + } + } + else if (modifier_mask & ShiftMask || (modifier_mask & LockMask && is_shift_lock) || modifier_mask & (ShiftMask + LockMask)) { + /* The Shift modifier is on, or the Lock modifier is on and + * is interpreted as ShiftLock, or both. In this case, the + * second KeySym is used. + */ + // index = 1 + keysym = keyboard_map[keycode *keysym_per_keycode + 1]; + } + else { + logger(LOG_LEVEL_ERROR, "%s [%u]: Unable to determine the KeySym index!\n", + __FUNCTION__, __LINE__); + } + } + #endif + + return keysym; +} +#endif + +void load_input_helper(Display *disp) { + #ifdef USE_XKB + /* The following code block is based on vncdisplaykeymap.c under the terms: + * + * Copyright (C) 2008 Anthony Liguori + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 2 as + * published by the Free Software Foundation. + */ + XkbDescPtr desc = XkbGetKeyboard(disp, XkbGBN_AllComponentsMask, XkbUseCoreKbd); + if (desc != NULL && desc->names != NULL) { + const char *layout_name = XGetAtomName(disp, desc->names->keycodes); + logger(LOG_LEVEL_DEBUG, + "%s [%u]: Found keycode atom '%s' (%i)!\n", + __FUNCTION__, __LINE__, layout_name, + (unsigned int) desc->names->keycodes); + + const char *prefix_xfree86 = "xfree86_"; + #if defined(USE_EVDEV) && defined(USE_XKB) + const char *prefix_evdev = "evdev_"; + if (strncmp(layout_name, prefix_evdev, strlen(prefix_evdev)) == 0) { + is_evdev = true; + } else + #endif + if (strncmp(layout_name, prefix_xfree86, strlen(prefix_xfree86)) != 0) { + // logger(LOG_LEVEL_ERROR, + // "%s [%u]: Unknown keycode name '%s', please file a bug report!\n", + // __FUNCTION__, __LINE__, layout_name); + } + else if (layout_name == NULL) { + logger(LOG_LEVEL_ERROR, + "%s [%u]: X atom name failure for desc->names->keycodes!\n", + __FUNCTION__, __LINE__); + } + + XkbFreeClientMap(desc, XkbGBN_AllComponentsMask, True); + } + else { + logger(LOG_LEVEL_ERROR, + "%s [%u]: XkbGetKeyboard failed to locate a valid keyboard!\n", + __FUNCTION__, __LINE__); + } + + // Get the map. + keyboard_map = XkbGetMap(disp, XkbAllClientInfoMask, XkbUseCoreKbd); + #else + // No known alternative to determine scancode mapping, assume XFree86! + // printf("%s\n", "No known alternative to determine scancode mapping, assume XFree86!"); + // #pragma message("*** Warning: XKB support is required to accurately determine keyboard scancodes!") + // #pragma message("... Assuming XFree86 keyboard layout.") + + logger(LOG_LEVEL_WARN, "%s [%u]: Using XFree86 keyboard layout.\n", + __FUNCTION__, __LINE__); + logger(LOG_LEVEL_WARN, "%s [%u]: XKB support is required to accurately determine keyboard characters!\n", + __FUNCTION__, __LINE__); + + int minKeyCode, maxKeyCode; + XDisplayKeycodes(disp, &minKeyCode, &maxKeyCode); + + keyboard_map = XGetKeyboardMapping(disp, minKeyCode, (maxKeyCode - minKeyCode + 1), &keysym_per_keycode); + if (keyboard_map) { + XModifierKeymap *modifierMap = XGetModifierMapping(disp); + + if (modifierMap) { + /* The Lock modifier is interpreted as CapsLock when the KeySym + * named XK_Caps_Lock is attached to some KeyCode and that KeyCode + * is attached to the Lock modifier. The Lock modifier is + * interpreted as ShiftLock when the KeySym named XK_Shift_Lock is + * attached to some KeyCode and that KeyCode is attached to the Lock + * modifier. If the Lock modifier could be interpreted as both + * CapsLock and ShiftLock, the CapsLock interpretation is used. + */ + + KeyCode capsLock = XKeysymToKeycode(disp, XK_Caps_Lock); + KeyCode shiftLock = XKeysymToKeycode(disp, XK_Shift_Lock); + keysym_per_keycode--; + + // Loop over the modifier map to find out if/where shift and caps locks are set. + int i; + for (i = LockMapIndex; i < LockMapIndex + modifierMap->max_keypermod && !is_caps_lock; i++) { + if (capsLock != 0 && modifierMap->modifiermap[i] == capsLock) { + is_caps_lock = true; + is_shift_lock = false; + } + else if (shiftLock != 0 && modifierMap->modifiermap[i] == shiftLock) { + is_shift_lock = true; + } + } + + XFree(modifierMap); + } + else { + XFree(keyboard_map); + + logger(LOG_LEVEL_ERROR, + "%s [%u]: Unable to get modifier mapping table!\n", + __FUNCTION__, __LINE__); + } + } + else { + logger(LOG_LEVEL_ERROR, + "%s [%u]: Unable to get keyboard mapping table!\n", + __FUNCTION__, __LINE__); + } + #endif +} + +void unload_input_helper() { + if (keyboard_map) { + #ifdef USE_XKB + XkbFreeClientMap(keyboard_map, XkbAllClientInfoMask, true); + #if defined(USE_EVDEV) && defined(USE_XKB) + is_evdev = false; + #endif + #else + XFree(keyboard_map); + #endif + } +} diff --git a/vendor/github.com/robotn/gohook/hook/x11/properties_c.h b/vendor/github.com/robotn/gohook/hook/x11/properties_c.h new file mode 100644 index 0000000..9358143 --- /dev/null +++ b/vendor/github.com/robotn/gohook/hook/x11/properties_c.h @@ -0,0 +1,499 @@ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#ifdef USE_XKB + #include +#endif +#ifdef USE_XF86MISC + #include + #include +#endif +#if defined(USE_XINERAMA) && !defined(USE_XRANDR) + #include +#elif defined(USE_XRANDR) +#include + #include +#endif +#ifdef USE_XT + #include + + static XtAppContext xt_context; + static Display *xt_disp; +#endif + +#include "../iohook.h" +#include "input.h" +// #include "../logger.h" + +Display *properties_disp; + +#ifdef USE_XRANDR +static pthread_mutex_t xrandr_mutex = PTHREAD_MUTEX_INITIALIZER; +static XRRScreenResources *xrandr_resources = NULL; + +static void settings_cleanup_proc(void *arg) { + if (pthread_mutex_trylock(&xrandr_mutex) == 0) { + if (xrandr_resources != NULL) { + XRRFreeScreenResources(xrandr_resources); + xrandr_resources = NULL; + } + + if (arg != NULL) { + XCloseDisplay((Display *) arg); + arg = NULL; + } + + pthread_mutex_unlock(&xrandr_mutex); + } +} + +static void *settings_thread_proc(void *arg) { + Display *settings_disp = XOpenDisplay(XDisplayName(NULL));; + if (settings_disp != NULL) { + logger(LOG_LEVEL_DEBUG, "%s [%u]: %s\n", + __FUNCTION__, __LINE__, "XOpenDisplay success."); + + pthread_cleanup_push(settings_cleanup_proc, settings_disp); + + int event_base = 0; + int error_base = 0; + if (XRRQueryExtension(settings_disp, &event_base, &error_base)) { + Window root = XDefaultRootWindow(settings_disp); + unsigned long event_mask = RRScreenChangeNotifyMask; + XRRSelectInput(settings_disp, root, event_mask); + + XEvent ev; + + while(settings_disp != NULL) { + XNextEvent(settings_disp, &ev); + + if (ev.type == event_base + RRScreenChangeNotifyMask) { + logger(LOG_LEVEL_DEBUG, "%s [%u]: Received XRRScreenChangeNotifyEvent.\n", + __FUNCTION__, __LINE__); + + pthread_mutex_lock(&xrandr_mutex); + if (xrandr_resources != NULL) { + XRRFreeScreenResources(xrandr_resources); + } + + xrandr_resources = XRRGetScreenResources(settings_disp, root); + if (xrandr_resources == NULL) { + logger(LOG_LEVEL_WARN, "%s [%u]: XRandR could not get screen resources!\n", + __FUNCTION__, __LINE__); + } + pthread_mutex_unlock(&xrandr_mutex); + } + else { + logger(LOG_LEVEL_WARN, "%s [%u]: XRandR is not currently available!\n", + __FUNCTION__, __LINE__); + } + } + } + + // Execute the thread cleanup handler. + pthread_cleanup_pop(1); + + } + else { + logger(LOG_LEVEL_ERROR, "%s [%u]: XOpenDisplay failure!\n", + __FUNCTION__, __LINE__); + } + + return NULL; +} +#endif + +IOHOOK_API screen_data* hook_create_screen_info(unsigned char *count) { + *count = 0; + screen_data *screens = NULL; + + #if defined(USE_XINERAMA) && !defined(USE_XRANDR) + if (XineramaIsActive(properties_disp)) { + int xine_count = 0; + XineramaScreenInfo *xine_info = XineramaQueryScreens(properties_disp, &xine_count); + + if (xine_info != NULL) { + if (xine_count > UINT8_MAX) { + *count = UINT8_MAX; + + logger(LOG_LEVEL_WARN, "%s [%u]: Screen count overflow detected!\n", + __FUNCTION__, __LINE__); + } + else { + *count = (uint8_t) xine_count; + } + + screens = malloc(sizeof(screen_data) * xine_count); + + if (screens != NULL) { + int i; + for (i = 0; i < xine_count; i++) { + screens[i] = (screen_data) { + .number = xine_info[i].screen_number, + .x = xine_info[i].x_org, + .y = xine_info[i].y_org, + .width = xine_info[i].width, + .height = xine_info[i].height + }; + } + } + + XFree(xine_info); + } + } + #elif defined(USE_XRANDR) + pthread_mutex_lock(&xrandr_mutex); + if (xrandr_resources != NULL) { + int xrandr_count = xrandr_resources->ncrtc; + if (xrandr_count > UINT8_MAX) { + *count = UINT8_MAX; + + logger(LOG_LEVEL_WARN, "%s [%u]: Screen count overflow detected!\n", + __FUNCTION__, __LINE__); + } + else { + *count = (uint8_t) xrandr_count; + } + + screens = malloc(sizeof(screen_data) * xrandr_count); + + if (screens != NULL) { + int i; + for (i = 0; i < xrandr_count; i++) { + XRRCrtcInfo *crtc_info = XRRGetCrtcInfo(properties_disp, xrandr_resources, xrandr_resources->crtcs[i]); + + if (crtc_info != NULL) { + screens[i] = (screen_data) { + .number = i + 1, + .x = crtc_info->x, + .y = crtc_info->y, + .width = crtc_info->width, + .height = crtc_info->height + }; + + XRRFreeCrtcInfo(crtc_info); + } + else { + logger(LOG_LEVEL_WARN, "%s [%u]: XRandr failed to return crtc information! (%#X)\n", + __FUNCTION__, __LINE__, xrandr_resources->crtcs[i]); + } + } + } + } + pthread_mutex_unlock(&xrandr_mutex); + #else + Screen* default_screen = DefaultScreenOfDisplay(properties_disp); + + if (default_screen->width > 0 && default_screen->height > 0) { + screens = malloc(sizeof(screen_data)); + + if (screens != NULL) { + *count = 1; + screens[0] = (screen_data) { + .number = 1, + .x = 0, + .y = 0, + .width = default_screen->width, + .height = default_screen->height + }; + } + } + #endif + + return screens; +} + +IOHOOK_API long int hook_get_auto_repeat_rate() { + bool successful = false; + long int value = -1; + unsigned int delay = 0, rate = 0; + + // Check and make sure we could connect to the x server. + if (properties_disp != NULL) { + #ifdef USE_XKB + // Attempt to acquire the keyboard auto repeat rate using the XKB extension. + if (!successful) { + successful = XkbGetAutoRepeatRate(properties_disp, XkbUseCoreKbd, &delay, &rate); + + if (successful) { + logger(LOG_LEVEL_INFO, "%s [%u]: XkbGetAutoRepeatRate: %u.\n", + __FUNCTION__, __LINE__, rate); + } + } + #endif + + #ifdef USE_XF86MISC + // Fallback to the XF86 Misc extension if available and other efforts failed. + if (!successful) { + XF86MiscKbdSettings kb_info; + successful = (bool) XF86MiscGetKbdSettings(properties_disp, &kb_info); + if (successful) { + logger(LOG_LEVEL_INFO, "%s [%u]: XF86MiscGetKbdSettings: %i.\n", + __FUNCTION__, __LINE__, kbdinfo.rate); + + delay = (unsigned int) kbdinfo.delay; + rate = (unsigned int) kbdinfo.rate; + } + } + #endif + } + else { + logger(LOG_LEVEL_ERROR, "%s [%u]: %s\n", + __FUNCTION__, __LINE__, "XOpenDisplay failure!"); + } + + if (successful) { + value = (long int) rate; + } + + return value; +} + +IOHOOK_API long int hook_get_auto_repeat_delay() { + bool successful = false; + long int value = -1; + unsigned int delay = 0, rate = 0; + + // Check and make sure we could connect to the x server. + if (properties_disp != NULL) { + #ifdef USE_XKB + // Attempt to acquire the keyboard auto repeat rate using the XKB extension. + if (!successful) { + successful = XkbGetAutoRepeatRate(properties_disp, XkbUseCoreKbd, &delay, &rate); + + if (successful) { + logger(LOG_LEVEL_INFO, "%s [%u]: XkbGetAutoRepeatRate: %u.\n", + __FUNCTION__, __LINE__, delay); + } + } + #endif + + #ifdef USE_XF86MISC + // Fallback to the XF86 Misc extension if available and other efforts failed. + if (!successful) { + XF86MiscKbdSettings kb_info; + successful = (bool) XF86MiscGetKbdSettings(properties_disp, &kb_info); + if (successful) { + logger(LOG_LEVEL_INFO, "%s [%u]: XF86MiscGetKbdSettings: %i.\n", + __FUNCTION__, __LINE__, kbdinfo.delay); + + delay = (unsigned int) kbdinfo.delay; + rate = (unsigned int) kbdinfo.rate; + } + } + #endif + } + else { + logger(LOG_LEVEL_ERROR, "%s [%u]: %s\n", + __FUNCTION__, __LINE__, "XOpenDisplay failure!"); + } + + if (successful) { + value = (long int) delay; + } + + return value; +} + +IOHOOK_API long int hook_get_pointer_acceleration_multiplier() { + long int value = -1; + int accel_numerator, accel_denominator, threshold; + + // Check and make sure we could connect to the x server. + if (properties_disp != NULL) { + XGetPointerControl(properties_disp, &accel_numerator, &accel_denominator, &threshold); + if (accel_denominator >= 0) { + logger(LOG_LEVEL_INFO, "%s [%u]: XGetPointerControl: %i.\n", + __FUNCTION__, __LINE__, accel_denominator); + + value = (long int) accel_denominator; + } + } + else { + logger(LOG_LEVEL_ERROR, "%s [%u]: %s\n", + __FUNCTION__, __LINE__, "XOpenDisplay failure!"); + } + + return value; +} + +IOHOOK_API long int hook_get_pointer_acceleration_threshold() { + long int value = -1; + int accel_numerator, accel_denominator, threshold; + + // Check and make sure we could connect to the x server. + if (properties_disp != NULL) { + XGetPointerControl(properties_disp, &accel_numerator, &accel_denominator, &threshold); + if (threshold >= 0) { + logger(LOG_LEVEL_INFO, "%s [%u]: XGetPointerControl: %i.\n", + __FUNCTION__, __LINE__, threshold); + + value = (long int) threshold; + } + } + else { + logger(LOG_LEVEL_ERROR, "%s [%u]: %s\n", + __FUNCTION__, __LINE__, "XOpenDisplay failure!"); + } + + return value; +} + +IOHOOK_API long int hook_get_pointer_sensitivity() { + long int value = -1; + int accel_numerator, accel_denominator, threshold; + + // Check and make sure we could connect to the x server. + if (properties_disp != NULL) { + XGetPointerControl(properties_disp, &accel_numerator, &accel_denominator, &threshold); + if (accel_numerator >= 0) { + logger(LOG_LEVEL_INFO, "%s [%u]: XGetPointerControl: %i.\n", + __FUNCTION__, __LINE__, accel_numerator); + + value = (long int) accel_numerator; + } + } + else { + logger(LOG_LEVEL_ERROR, "%s [%u]: %s\n", + __FUNCTION__, __LINE__, "XOpenDisplay failure!"); + } + + return value; +} + +IOHOOK_API long int hook_get_multi_click_time() { + long int value = 200; + int click_time; + bool successful = false; + + #ifdef USE_XT + // Check and make sure we could connect to the x server. + if (xt_disp != NULL) { + // Try and use the Xt extention to get the current multi-click. + if (!successful) { + // Fall back to the X Toolkit extension if available and other efforts failed. + click_time = XtGetMultiClickTime(xt_disp); + if (click_time >= 0) { + logger(LOG_LEVEL_INFO, "%s [%u]: XtGetMultiClickTime: %i.\n", + __FUNCTION__, __LINE__, click_time); + + successful = true; + } + } + } + else { + logger(LOG_LEVEL_ERROR, "%s [%u]: %s\n", + __FUNCTION__, __LINE__, "XOpenDisplay failure!"); + } + #endif + + // Check and make sure we could connect to the x server. + if (properties_disp != NULL) { + // Try and acquire the multi-click time from the user defined X defaults. + if (!successful) { + char *xprop = XGetDefault(properties_disp, "*", "multiClickTime"); + if (xprop != NULL && sscanf(xprop, "%4i", &click_time) != EOF) { + logger(LOG_LEVEL_INFO, "%s [%u]: X default 'multiClickTime' property: %i.\n", + __FUNCTION__, __LINE__, click_time); + + successful = true; + } + } + + if (!successful) { + char *xprop = XGetDefault(properties_disp, "OpenWindows", "MultiClickTimeout"); + if (xprop != NULL && sscanf(xprop, "%4i", &click_time) != EOF) { + logger(LOG_LEVEL_INFO, "%s [%u]: X default 'MultiClickTimeout' property: %i.\n", + __FUNCTION__, __LINE__, click_time); + + successful = true; + } + } + } + else { + logger(LOG_LEVEL_ERROR, "%s [%u]: %s\n", + __FUNCTION__, __LINE__, "XOpenDisplay failure!"); + } + + if (successful) { + value = (long int) click_time; + } + + return value; +} + +// Create a shared object constructor. +__attribute__ ((constructor)) +void on_library_load() { + // Make sure we are initialized for threading. + XInitThreads(); + + // Open local display. + properties_disp = XOpenDisplay(XDisplayName(NULL)); + if (properties_disp == NULL) { + logger(LOG_LEVEL_ERROR, "%s [%u]: %s\n", + __FUNCTION__, __LINE__, "XOpenDisplay failure!"); + } + else { + logger(LOG_LEVEL_DEBUG, "%s [%u]: %s\n", + __FUNCTION__, __LINE__, "XOpenDisplay success."); + } + + #ifdef USE_XRANDR + // Create the thread attribute. + pthread_attr_t settings_thread_attr; + pthread_attr_init(&settings_thread_attr); + + pthread_t settings_thread_id; + if (pthread_create(&settings_thread_id, &settings_thread_attr, settings_thread_proc, NULL) == 0) { + logger(LOG_LEVEL_DEBUG, "%s [%u]: Successfully created settings thread.\n", + __FUNCTION__, __LINE__); + } + else { + logger(LOG_LEVEL_ERROR, "%s [%u]: Failed to create settings thread!\n", + __FUNCTION__, __LINE__); + } + + // Make sure the thread attribute is removed. + pthread_attr_destroy(&settings_thread_attr); + #endif + + #ifdef USE_XT + XtToolkitInitialize(); + xt_context = XtCreateApplicationContext(); + + int argc = 0; + char ** argv = { NULL }; + xt_disp = XtOpenDisplay(xt_context, NULL, "IOHook", "libIOhook", NULL, 0, &argc, argv); + #endif + + // Initialize. + load_input_helper(properties_disp); +} + +// Create a shared object destructor. +__attribute__ ((destructor)) +void on_library_unload() { + // Disable the event hook. + //hook_stop(); + + // Cleanup. + unload_input_helper(); + + #ifdef USE_XT + XtCloseDisplay(xt_disp); + XtDestroyApplicationContext(xt_context); + #endif + + // Destroy the native displays. + if (properties_disp != NULL) { + XCloseDisplay(properties_disp); + properties_disp = NULL; + } +} diff --git a/vendor/golang.org/x/sys/unix/mkerrors.sh b/vendor/golang.org/x/sys/unix/mkerrors.sh index 1d40fc4..a2baa81 100755 --- a/vendor/golang.org/x/sys/unix/mkerrors.sh +++ b/vendor/golang.org/x/sys/unix/mkerrors.sh @@ -456,6 +456,7 @@ ccflags="$@" $2 ~ /^PERF_EVENT_IOC_/ || $2 ~ /^SECCOMP_MODE_/ || $2 ~ /^SPLICE_/ || + $2 ~ /^SYNC_FILE_RANGE_/ || $2 !~ /^AUDIT_RECORD_MAGIC/ && $2 !~ /IOC_MAGIC/ && $2 ~ /^[A-Z][A-Z0-9_]+_MAGIC2?$/ || diff --git a/vendor/golang.org/x/sys/unix/syscall_linux_ppc64x.go b/vendor/golang.org/x/sys/unix/syscall_linux_ppc64x.go index 8c6720f..6a38dfd 100644 --- a/vendor/golang.org/x/sys/unix/syscall_linux_ppc64x.go +++ b/vendor/golang.org/x/sys/unix/syscall_linux_ppc64x.go @@ -44,7 +44,6 @@ package unix //sys Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error) //sys Stat(path string, stat *Stat_t) (err error) //sys Statfs(path string, buf *Statfs_t) (err error) -//sys SyncFileRange(fd int, off int64, n int64, flags int) (err error) = SYS_SYNC_FILE_RANGE2 //sys Truncate(path string, length int64) (err error) //sys Ustat(dev int, ubuf *Ustat_t) (err error) //sys accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) @@ -129,3 +128,11 @@ func Poll(fds []PollFd, timeout int) (n int, err error) { } return poll(&fds[0], len(fds), timeout) } + +//sys syncFileRange2(fd int, flags int, off int64, n int64) (err error) = SYS_SYNC_FILE_RANGE2 + +func SyncFileRange(fd int, off int64, n int64, flags int) error { + // The sync_file_range and sync_file_range2 syscalls differ only in the + // order of their arguments. + return syncFileRange2(fd, flags, off, n) +} diff --git a/vendor/golang.org/x/sys/unix/syscall_linux_riscv64.go b/vendor/golang.org/x/sys/unix/syscall_linux_riscv64.go new file mode 100644 index 0000000..512077f --- /dev/null +++ b/vendor/golang.org/x/sys/unix/syscall_linux_riscv64.go @@ -0,0 +1,212 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build riscv64,linux + +package unix + +import "unsafe" + +func EpollCreate(size int) (fd int, err error) { + if size <= 0 { + return -1, EINVAL + } + return EpollCreate1(0) +} + +//sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) = SYS_EPOLL_PWAIT +//sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64 +//sys Fchown(fd int, uid int, gid int) (err error) +//sys Fstat(fd int, stat *Stat_t) (err error) +//sys Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) +//sys Fstatfs(fd int, buf *Statfs_t) (err error) +//sys Ftruncate(fd int, length int64) (err error) +//sysnb Getegid() (egid int) +//sysnb Geteuid() (euid int) +//sysnb Getgid() (gid int) +//sysnb Getrlimit(resource int, rlim *Rlimit) (err error) +//sysnb Getuid() (uid int) +//sys Listen(s int, n int) (err error) +//sys Pread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64 +//sys Pwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64 +//sys Seek(fd int, offset int64, whence int) (off int64, err error) = SYS_LSEEK + +func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) { + var ts *Timespec + if timeout != nil { + ts = &Timespec{Sec: timeout.Sec, Nsec: timeout.Usec * 1000} + } + return Pselect(nfd, r, w, e, ts, nil) +} + +//sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) +//sys Setfsgid(gid int) (err error) +//sys Setfsuid(uid int) (err error) +//sysnb Setregid(rgid int, egid int) (err error) +//sysnb Setresgid(rgid int, egid int, sgid int) (err error) +//sysnb Setresuid(ruid int, euid int, suid int) (err error) +//sysnb Setrlimit(resource int, rlim *Rlimit) (err error) +//sysnb Setreuid(ruid int, euid int) (err error) +//sys Shutdown(fd int, how int) (err error) +//sys Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error) + +func Stat(path string, stat *Stat_t) (err error) { + return Fstatat(AT_FDCWD, path, stat, 0) +} + +func Lchown(path string, uid int, gid int) (err error) { + return Fchownat(AT_FDCWD, path, uid, gid, AT_SYMLINK_NOFOLLOW) +} + +func Lstat(path string, stat *Stat_t) (err error) { + return Fstatat(AT_FDCWD, path, stat, AT_SYMLINK_NOFOLLOW) +} + +//sys Statfs(path string, buf *Statfs_t) (err error) +//sys SyncFileRange(fd int, off int64, n int64, flags int) (err error) +//sys Truncate(path string, length int64) (err error) + +func Ustat(dev int, ubuf *Ustat_t) (err error) { + return ENOSYS +} + +//sys accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) +//sys accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error) +//sys bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) +//sys connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) +//sysnb getgroups(n int, list *_Gid_t) (nn int, err error) +//sysnb setgroups(n int, list *_Gid_t) (err error) +//sys getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error) +//sys setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error) +//sysnb socket(domain int, typ int, proto int) (fd int, err error) +//sysnb socketpair(domain int, typ int, proto int, fd *[2]int32) (err error) +//sysnb getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) +//sysnb getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) +//sys recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) +//sys sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) +//sys recvmsg(s int, msg *Msghdr, flags int) (n int, err error) +//sys sendmsg(s int, msg *Msghdr, flags int) (n int, err error) +//sys mmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset int64) (xaddr uintptr, err error) + +//sysnb Gettimeofday(tv *Timeval) (err error) + +func setTimespec(sec, nsec int64) Timespec { + return Timespec{Sec: sec, Nsec: nsec} +} + +func setTimeval(sec, usec int64) Timeval { + return Timeval{Sec: sec, Usec: usec} +} + +func futimesat(dirfd int, path string, tv *[2]Timeval) (err error) { + if tv == nil { + return utimensat(dirfd, path, nil, 0) + } + + ts := []Timespec{ + NsecToTimespec(TimevalToNsec(tv[0])), + NsecToTimespec(TimevalToNsec(tv[1])), + } + return utimensat(dirfd, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0) +} + +func Time(t *Time_t) (Time_t, error) { + var tv Timeval + err := Gettimeofday(&tv) + if err != nil { + return 0, err + } + if t != nil { + *t = Time_t(tv.Sec) + } + return Time_t(tv.Sec), nil +} + +func Utime(path string, buf *Utimbuf) error { + tv := []Timeval{ + {Sec: buf.Actime}, + {Sec: buf.Modtime}, + } + return Utimes(path, tv) +} + +func utimes(path string, tv *[2]Timeval) (err error) { + if tv == nil { + return utimensat(AT_FDCWD, path, nil, 0) + } + + ts := []Timespec{ + NsecToTimespec(TimevalToNsec(tv[0])), + NsecToTimespec(TimevalToNsec(tv[1])), + } + return utimensat(AT_FDCWD, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0) +} + +func Pipe(p []int) (err error) { + if len(p) != 2 { + return EINVAL + } + var pp [2]_C_int + err = pipe2(&pp, 0) + p[0] = int(pp[0]) + p[1] = int(pp[1]) + return +} + +//sysnb pipe2(p *[2]_C_int, flags int) (err error) + +func Pipe2(p []int, flags int) (err error) { + if len(p) != 2 { + return EINVAL + } + var pp [2]_C_int + err = pipe2(&pp, flags) + p[0] = int(pp[0]) + p[1] = int(pp[1]) + return +} + +func (r *PtraceRegs) PC() uint64 { return r.Pc } + +func (r *PtraceRegs) SetPC(pc uint64) { r.Pc = pc } + +func (iov *Iovec) SetLen(length int) { + iov.Len = uint64(length) +} + +func (msghdr *Msghdr) SetControllen(length int) { + msghdr.Controllen = uint64(length) +} + +func (cmsg *Cmsghdr) SetLen(length int) { + cmsg.Len = uint64(length) +} + +func InotifyInit() (fd int, err error) { + return InotifyInit1(0) +} + +func Dup2(oldfd int, newfd int) (err error) { + return Dup3(oldfd, newfd, 0) +} + +func Pause() (err error) { + _, _, e1 := Syscall6(SYS_PPOLL, 0, 0, 0, 0, 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +func Poll(fds []PollFd, timeout int) (n int, err error) { + var ts *Timespec + if timeout >= 0 { + ts = new(Timespec) + *ts = NsecToTimespec(int64(timeout) * 1e6) + } + if len(fds) == 0 { + return ppoll(nil, 0, ts, nil) + } + return ppoll(&fds[0], len(fds), ts, nil) +} diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_386.go b/vendor/golang.org/x/sys/unix/zerrors_linux_386.go index a1699fb..f33613e 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_386.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_386.go @@ -1891,6 +1891,9 @@ const ( STATX_TYPE = 0x1 STATX_UID = 0x8 STATX__RESERVED = 0x80000000 + SYNC_FILE_RANGE_WAIT_AFTER = 0x4 + SYNC_FILE_RANGE_WAIT_BEFORE = 0x1 + SYNC_FILE_RANGE_WRITE = 0x2 SYSFS_MAGIC = 0x62656572 S_BLKSIZE = 0x200 S_IEXEC = 0x40 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go index 8653d86..ccdbebf 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go @@ -1892,6 +1892,9 @@ const ( STATX_TYPE = 0x1 STATX_UID = 0x8 STATX__RESERVED = 0x80000000 + SYNC_FILE_RANGE_WAIT_AFTER = 0x4 + SYNC_FILE_RANGE_WAIT_BEFORE = 0x1 + SYNC_FILE_RANGE_WRITE = 0x2 SYSFS_MAGIC = 0x62656572 S_BLKSIZE = 0x200 S_IEXEC = 0x40 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go b/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go index e1595b3..770d4c7 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go @@ -1898,6 +1898,9 @@ const ( STATX_TYPE = 0x1 STATX_UID = 0x8 STATX__RESERVED = 0x80000000 + SYNC_FILE_RANGE_WAIT_AFTER = 0x4 + SYNC_FILE_RANGE_WAIT_BEFORE = 0x1 + SYNC_FILE_RANGE_WRITE = 0x2 SYSFS_MAGIC = 0x62656572 S_BLKSIZE = 0x200 S_IEXEC = 0x40 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go index fe43d17..c3e311d 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go @@ -1883,6 +1883,9 @@ const ( STATX_UID = 0x8 STATX__RESERVED = 0x80000000 SVE_MAGIC = 0x53564501 + SYNC_FILE_RANGE_WAIT_AFTER = 0x4 + SYNC_FILE_RANGE_WAIT_BEFORE = 0x1 + SYNC_FILE_RANGE_WRITE = 0x2 SYSFS_MAGIC = 0x62656572 S_BLKSIZE = 0x200 S_IEXEC = 0x40 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go b/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go index 845c049..9fee271 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go @@ -1892,6 +1892,9 @@ const ( STATX_TYPE = 0x1 STATX_UID = 0x8 STATX__RESERVED = 0x80000000 + SYNC_FILE_RANGE_WAIT_AFTER = 0x4 + SYNC_FILE_RANGE_WAIT_BEFORE = 0x1 + SYNC_FILE_RANGE_WRITE = 0x2 SYSFS_MAGIC = 0x62656572 S_BLKSIZE = 0x200 S_IEXEC = 0x40 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go index b791d86..d022427 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go @@ -1892,6 +1892,9 @@ const ( STATX_TYPE = 0x1 STATX_UID = 0x8 STATX__RESERVED = 0x80000000 + SYNC_FILE_RANGE_WAIT_AFTER = 0x4 + SYNC_FILE_RANGE_WAIT_BEFORE = 0x1 + SYNC_FILE_RANGE_WRITE = 0x2 SYSFS_MAGIC = 0x62656572 S_BLKSIZE = 0x200 S_IEXEC = 0x40 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go index d1b9568..509faae 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go @@ -1892,6 +1892,9 @@ const ( STATX_TYPE = 0x1 STATX_UID = 0x8 STATX__RESERVED = 0x80000000 + SYNC_FILE_RANGE_WAIT_AFTER = 0x4 + SYNC_FILE_RANGE_WAIT_BEFORE = 0x1 + SYNC_FILE_RANGE_WRITE = 0x2 SYSFS_MAGIC = 0x62656572 S_BLKSIZE = 0x200 S_IEXEC = 0x40 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go b/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go index 2735466..340f78a 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go @@ -1892,6 +1892,9 @@ const ( STATX_TYPE = 0x1 STATX_UID = 0x8 STATX__RESERVED = 0x80000000 + SYNC_FILE_RANGE_WAIT_AFTER = 0x4 + SYNC_FILE_RANGE_WAIT_BEFORE = 0x1 + SYNC_FILE_RANGE_WRITE = 0x2 SYSFS_MAGIC = 0x62656572 S_BLKSIZE = 0x200 S_IEXEC = 0x40 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go index 506ba25..4e80d6a 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go @@ -1947,6 +1947,9 @@ const ( STATX_TYPE = 0x1 STATX_UID = 0x8 STATX__RESERVED = 0x80000000 + SYNC_FILE_RANGE_WAIT_AFTER = 0x4 + SYNC_FILE_RANGE_WAIT_BEFORE = 0x1 + SYNC_FILE_RANGE_WRITE = 0x2 SYSFS_MAGIC = 0x62656572 S_BLKSIZE = 0x200 S_IEXEC = 0x40 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go index b480cd1..f22c0d6 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go @@ -1947,6 +1947,9 @@ const ( STATX_TYPE = 0x1 STATX_UID = 0x8 STATX__RESERVED = 0x80000000 + SYNC_FILE_RANGE_WAIT_AFTER = 0x4 + SYNC_FILE_RANGE_WAIT_BEFORE = 0x1 + SYNC_FILE_RANGE_WRITE = 0x2 SYSFS_MAGIC = 0x62656572 S_BLKSIZE = 0x200 S_IEXEC = 0x40 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go new file mode 100644 index 0000000..0978dba --- /dev/null +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go @@ -0,0 +1,2625 @@ +// mkerrors.sh -Wall -Werror -static -I/tmp/include +// Code generated by the command above; see README.md. DO NOT EDIT. + +// +build riscv64,linux + +// Code generated by cmd/cgo -godefs; DO NOT EDIT. +// cgo -godefs -- -Wall -Werror -static -I/tmp/include _const.go + +package unix + +import "syscall" + +const ( + AAFS_MAGIC = 0x5a3c69f0 + ADFS_SUPER_MAGIC = 0xadf5 + AFFS_SUPER_MAGIC = 0xadff + AFS_FS_MAGIC = 0x6b414653 + AFS_SUPER_MAGIC = 0x5346414f + AF_ALG = 0x26 + AF_APPLETALK = 0x5 + AF_ASH = 0x12 + AF_ATMPVC = 0x8 + AF_ATMSVC = 0x14 + AF_AX25 = 0x3 + AF_BLUETOOTH = 0x1f + AF_BRIDGE = 0x7 + AF_CAIF = 0x25 + AF_CAN = 0x1d + AF_DECnet = 0xc + AF_ECONET = 0x13 + AF_FILE = 0x1 + AF_IB = 0x1b + AF_IEEE802154 = 0x24 + AF_INET = 0x2 + AF_INET6 = 0xa + AF_IPX = 0x4 + AF_IRDA = 0x17 + AF_ISDN = 0x22 + AF_IUCV = 0x20 + AF_KCM = 0x29 + AF_KEY = 0xf + AF_LLC = 0x1a + AF_LOCAL = 0x1 + AF_MAX = 0x2c + AF_MPLS = 0x1c + AF_NETBEUI = 0xd + AF_NETLINK = 0x10 + AF_NETROM = 0x6 + AF_NFC = 0x27 + AF_PACKET = 0x11 + AF_PHONET = 0x23 + AF_PPPOX = 0x18 + AF_QIPCRTR = 0x2a + AF_RDS = 0x15 + AF_ROSE = 0xb + AF_ROUTE = 0x10 + AF_RXRPC = 0x21 + AF_SECURITY = 0xe + AF_SMC = 0x2b + AF_SNA = 0x16 + AF_TIPC = 0x1e + AF_UNIX = 0x1 + AF_UNSPEC = 0x0 + AF_VSOCK = 0x28 + AF_WANPIPE = 0x19 + AF_X25 = 0x9 + ALG_OP_DECRYPT = 0x0 + ALG_OP_ENCRYPT = 0x1 + ALG_SET_AEAD_ASSOCLEN = 0x4 + ALG_SET_AEAD_AUTHSIZE = 0x5 + ALG_SET_IV = 0x2 + ALG_SET_KEY = 0x1 + ALG_SET_OP = 0x3 + ANON_INODE_FS_MAGIC = 0x9041934 + ARPHRD_6LOWPAN = 0x339 + ARPHRD_ADAPT = 0x108 + ARPHRD_APPLETLK = 0x8 + ARPHRD_ARCNET = 0x7 + ARPHRD_ASH = 0x30d + ARPHRD_ATM = 0x13 + ARPHRD_AX25 = 0x3 + ARPHRD_BIF = 0x307 + ARPHRD_CAIF = 0x336 + ARPHRD_CAN = 0x118 + ARPHRD_CHAOS = 0x5 + ARPHRD_CISCO = 0x201 + ARPHRD_CSLIP = 0x101 + ARPHRD_CSLIP6 = 0x103 + ARPHRD_DDCMP = 0x205 + ARPHRD_DLCI = 0xf + ARPHRD_ECONET = 0x30e + ARPHRD_EETHER = 0x2 + ARPHRD_ETHER = 0x1 + ARPHRD_EUI64 = 0x1b + ARPHRD_FCAL = 0x311 + ARPHRD_FCFABRIC = 0x313 + ARPHRD_FCPL = 0x312 + ARPHRD_FCPP = 0x310 + ARPHRD_FDDI = 0x306 + ARPHRD_FRAD = 0x302 + ARPHRD_HDLC = 0x201 + ARPHRD_HIPPI = 0x30c + ARPHRD_HWX25 = 0x110 + ARPHRD_IEEE1394 = 0x18 + ARPHRD_IEEE802 = 0x6 + ARPHRD_IEEE80211 = 0x321 + ARPHRD_IEEE80211_PRISM = 0x322 + ARPHRD_IEEE80211_RADIOTAP = 0x323 + ARPHRD_IEEE802154 = 0x324 + ARPHRD_IEEE802154_MONITOR = 0x325 + ARPHRD_IEEE802_TR = 0x320 + ARPHRD_INFINIBAND = 0x20 + ARPHRD_IP6GRE = 0x337 + ARPHRD_IPDDP = 0x309 + ARPHRD_IPGRE = 0x30a + ARPHRD_IRDA = 0x30f + ARPHRD_LAPB = 0x204 + ARPHRD_LOCALTLK = 0x305 + ARPHRD_LOOPBACK = 0x304 + ARPHRD_METRICOM = 0x17 + ARPHRD_NETLINK = 0x338 + ARPHRD_NETROM = 0x0 + ARPHRD_NONE = 0xfffe + ARPHRD_PHONET = 0x334 + ARPHRD_PHONET_PIPE = 0x335 + ARPHRD_PIMREG = 0x30b + ARPHRD_PPP = 0x200 + ARPHRD_PRONET = 0x4 + ARPHRD_RAWHDLC = 0x206 + ARPHRD_RAWIP = 0x207 + ARPHRD_ROSE = 0x10e + ARPHRD_RSRVD = 0x104 + ARPHRD_SIT = 0x308 + ARPHRD_SKIP = 0x303 + ARPHRD_SLIP = 0x100 + ARPHRD_SLIP6 = 0x102 + ARPHRD_TUNNEL = 0x300 + ARPHRD_TUNNEL6 = 0x301 + ARPHRD_VOID = 0xffff + ARPHRD_VSOCKMON = 0x33a + ARPHRD_X25 = 0x10f + AUTOFS_SUPER_MAGIC = 0x187 + B0 = 0x0 + B1000000 = 0x1008 + B110 = 0x3 + B115200 = 0x1002 + B1152000 = 0x1009 + B1200 = 0x9 + B134 = 0x4 + B150 = 0x5 + B1500000 = 0x100a + B1800 = 0xa + B19200 = 0xe + B200 = 0x6 + B2000000 = 0x100b + B230400 = 0x1003 + B2400 = 0xb + B2500000 = 0x100c + B300 = 0x7 + B3000000 = 0x100d + B3500000 = 0x100e + B38400 = 0xf + B4000000 = 0x100f + B460800 = 0x1004 + B4800 = 0xc + B50 = 0x1 + B500000 = 0x1005 + B57600 = 0x1001 + B576000 = 0x1006 + B600 = 0x8 + B75 = 0x2 + B921600 = 0x1007 + B9600 = 0xd + BALLOON_KVM_MAGIC = 0x13661366 + BDEVFS_MAGIC = 0x62646576 + BINFMTFS_MAGIC = 0x42494e4d + BLKBSZGET = 0x80081270 + BLKBSZSET = 0x40081271 + BLKFLSBUF = 0x1261 + BLKFRAGET = 0x1265 + BLKFRASET = 0x1264 + BLKGETSIZE = 0x1260 + BLKGETSIZE64 = 0x80081272 + BLKPBSZGET = 0x127b + BLKRAGET = 0x1263 + BLKRASET = 0x1262 + BLKROGET = 0x125e + BLKROSET = 0x125d + BLKRRPART = 0x125f + BLKSECTGET = 0x1267 + BLKSECTSET = 0x1266 + BLKSSZGET = 0x1268 + BOTHER = 0x1000 + BPF_A = 0x10 + BPF_ABS = 0x20 + BPF_ADD = 0x0 + BPF_ALU = 0x4 + BPF_AND = 0x50 + BPF_B = 0x10 + BPF_DIV = 0x30 + BPF_FS_MAGIC = 0xcafe4a11 + BPF_H = 0x8 + BPF_IMM = 0x0 + BPF_IND = 0x40 + BPF_JA = 0x0 + BPF_JEQ = 0x10 + BPF_JGE = 0x30 + BPF_JGT = 0x20 + BPF_JMP = 0x5 + BPF_JSET = 0x40 + BPF_K = 0x0 + BPF_LD = 0x0 + BPF_LDX = 0x1 + BPF_LEN = 0x80 + BPF_LL_OFF = -0x200000 + BPF_LSH = 0x60 + BPF_MAJOR_VERSION = 0x1 + BPF_MAXINSNS = 0x1000 + BPF_MEM = 0x60 + BPF_MEMWORDS = 0x10 + BPF_MINOR_VERSION = 0x1 + BPF_MISC = 0x7 + BPF_MOD = 0x90 + BPF_MSH = 0xa0 + BPF_MUL = 0x20 + BPF_NEG = 0x80 + BPF_NET_OFF = -0x100000 + BPF_OR = 0x40 + BPF_RET = 0x6 + BPF_RSH = 0x70 + BPF_ST = 0x2 + BPF_STX = 0x3 + BPF_SUB = 0x10 + BPF_TAX = 0x0 + BPF_TXA = 0x80 + BPF_W = 0x0 + BPF_X = 0x8 + BPF_XOR = 0xa0 + BRKINT = 0x2 + BS0 = 0x0 + BS1 = 0x2000 + BSDLY = 0x2000 + BTRFS_SUPER_MAGIC = 0x9123683e + BTRFS_TEST_MAGIC = 0x73727279 + CAN_BCM = 0x2 + CAN_EFF_FLAG = 0x80000000 + CAN_EFF_ID_BITS = 0x1d + CAN_EFF_MASK = 0x1fffffff + CAN_ERR_FLAG = 0x20000000 + CAN_ERR_MASK = 0x1fffffff + CAN_INV_FILTER = 0x20000000 + CAN_ISOTP = 0x6 + CAN_MAX_DLC = 0x8 + CAN_MAX_DLEN = 0x8 + CAN_MCNET = 0x5 + CAN_MTU = 0x10 + CAN_NPROTO = 0x7 + CAN_RAW = 0x1 + CAN_RAW_FILTER_MAX = 0x200 + CAN_RTR_FLAG = 0x40000000 + CAN_SFF_ID_BITS = 0xb + CAN_SFF_MASK = 0x7ff + CAN_TP16 = 0x3 + CAN_TP20 = 0x4 + CBAUD = 0x100f + CBAUDEX = 0x1000 + CFLUSH = 0xf + CGROUP2_SUPER_MAGIC = 0x63677270 + CGROUP_SUPER_MAGIC = 0x27e0eb + CIBAUD = 0x100f0000 + CLOCAL = 0x800 + CLOCK_BOOTTIME = 0x7 + CLOCK_BOOTTIME_ALARM = 0x9 + CLOCK_DEFAULT = 0x0 + CLOCK_EXT = 0x1 + CLOCK_INT = 0x2 + CLOCK_MONOTONIC = 0x1 + CLOCK_MONOTONIC_COARSE = 0x6 + CLOCK_MONOTONIC_RAW = 0x4 + CLOCK_PROCESS_CPUTIME_ID = 0x2 + CLOCK_REALTIME = 0x0 + CLOCK_REALTIME_ALARM = 0x8 + CLOCK_REALTIME_COARSE = 0x5 + CLOCK_TAI = 0xb + CLOCK_THREAD_CPUTIME_ID = 0x3 + CLOCK_TXFROMRX = 0x4 + CLOCK_TXINT = 0x3 + CLONE_CHILD_CLEARTID = 0x200000 + CLONE_CHILD_SETTID = 0x1000000 + CLONE_DETACHED = 0x400000 + CLONE_FILES = 0x400 + CLONE_FS = 0x200 + CLONE_IO = 0x80000000 + CLONE_NEWCGROUP = 0x2000000 + CLONE_NEWIPC = 0x8000000 + CLONE_NEWNET = 0x40000000 + CLONE_NEWNS = 0x20000 + CLONE_NEWPID = 0x20000000 + CLONE_NEWUSER = 0x10000000 + CLONE_NEWUTS = 0x4000000 + CLONE_PARENT = 0x8000 + CLONE_PARENT_SETTID = 0x100000 + CLONE_PTRACE = 0x2000 + CLONE_SETTLS = 0x80000 + CLONE_SIGHAND = 0x800 + CLONE_SYSVSEM = 0x40000 + CLONE_THREAD = 0x10000 + CLONE_UNTRACED = 0x800000 + CLONE_VFORK = 0x4000 + CLONE_VM = 0x100 + CMSPAR = 0x40000000 + CODA_SUPER_MAGIC = 0x73757245 + CR0 = 0x0 + CR1 = 0x200 + CR2 = 0x400 + CR3 = 0x600 + CRAMFS_MAGIC = 0x28cd3d45 + CRDLY = 0x600 + CREAD = 0x80 + CRTSCTS = 0x80000000 + CS5 = 0x0 + CS6 = 0x10 + CS7 = 0x20 + CS8 = 0x30 + CSIGNAL = 0xff + CSIZE = 0x30 + CSTART = 0x11 + CSTATUS = 0x0 + CSTOP = 0x13 + CSTOPB = 0x40 + CSUSP = 0x1a + DAXFS_MAGIC = 0x64646178 + DEBUGFS_MAGIC = 0x64626720 + DEVPTS_SUPER_MAGIC = 0x1cd1 + DT_BLK = 0x6 + DT_CHR = 0x2 + DT_DIR = 0x4 + DT_FIFO = 0x1 + DT_LNK = 0xa + DT_REG = 0x8 + DT_SOCK = 0xc + DT_UNKNOWN = 0x0 + DT_WHT = 0xe + ECHO = 0x8 + ECHOCTL = 0x200 + ECHOE = 0x10 + ECHOK = 0x20 + ECHOKE = 0x800 + ECHONL = 0x40 + ECHOPRT = 0x400 + ECRYPTFS_SUPER_MAGIC = 0xf15f + EFD_CLOEXEC = 0x80000 + EFD_NONBLOCK = 0x800 + EFD_SEMAPHORE = 0x1 + EFIVARFS_MAGIC = 0xde5e81e4 + EFS_SUPER_MAGIC = 0x414a53 + ENCODING_DEFAULT = 0x0 + ENCODING_FM_MARK = 0x3 + ENCODING_FM_SPACE = 0x4 + ENCODING_MANCHESTER = 0x5 + ENCODING_NRZ = 0x1 + ENCODING_NRZI = 0x2 + EPOLLERR = 0x8 + EPOLLET = 0x80000000 + EPOLLEXCLUSIVE = 0x10000000 + EPOLLHUP = 0x10 + EPOLLIN = 0x1 + EPOLLMSG = 0x400 + EPOLLONESHOT = 0x40000000 + EPOLLOUT = 0x4 + EPOLLPRI = 0x2 + EPOLLRDBAND = 0x80 + EPOLLRDHUP = 0x2000 + EPOLLRDNORM = 0x40 + EPOLLWAKEUP = 0x20000000 + EPOLLWRBAND = 0x200 + EPOLLWRNORM = 0x100 + EPOLL_CLOEXEC = 0x80000 + EPOLL_CTL_ADD = 0x1 + EPOLL_CTL_DEL = 0x2 + EPOLL_CTL_MOD = 0x3 + ETH_P_1588 = 0x88f7 + ETH_P_8021AD = 0x88a8 + ETH_P_8021AH = 0x88e7 + ETH_P_8021Q = 0x8100 + ETH_P_80221 = 0x8917 + ETH_P_802_2 = 0x4 + ETH_P_802_3 = 0x1 + ETH_P_802_3_MIN = 0x600 + ETH_P_802_EX1 = 0x88b5 + ETH_P_AARP = 0x80f3 + ETH_P_AF_IUCV = 0xfbfb + ETH_P_ALL = 0x3 + ETH_P_AOE = 0x88a2 + ETH_P_ARCNET = 0x1a + ETH_P_ARP = 0x806 + ETH_P_ATALK = 0x809b + ETH_P_ATMFATE = 0x8884 + ETH_P_ATMMPOA = 0x884c + ETH_P_AX25 = 0x2 + ETH_P_BATMAN = 0x4305 + ETH_P_BPQ = 0x8ff + ETH_P_CAIF = 0xf7 + ETH_P_CAN = 0xc + ETH_P_CANFD = 0xd + ETH_P_CONTROL = 0x16 + ETH_P_CUST = 0x6006 + ETH_P_DDCMP = 0x6 + ETH_P_DEC = 0x6000 + ETH_P_DIAG = 0x6005 + ETH_P_DNA_DL = 0x6001 + ETH_P_DNA_RC = 0x6002 + ETH_P_DNA_RT = 0x6003 + ETH_P_DSA = 0x1b + ETH_P_ECONET = 0x18 + ETH_P_EDSA = 0xdada + ETH_P_ERSPAN = 0x88be + ETH_P_ERSPAN2 = 0x22eb + ETH_P_FCOE = 0x8906 + ETH_P_FIP = 0x8914 + ETH_P_HDLC = 0x19 + ETH_P_HSR = 0x892f + ETH_P_IBOE = 0x8915 + ETH_P_IEEE802154 = 0xf6 + ETH_P_IEEEPUP = 0xa00 + ETH_P_IEEEPUPAT = 0xa01 + ETH_P_IFE = 0xed3e + ETH_P_IP = 0x800 + ETH_P_IPV6 = 0x86dd + ETH_P_IPX = 0x8137 + ETH_P_IRDA = 0x17 + ETH_P_LAT = 0x6004 + ETH_P_LINK_CTL = 0x886c + ETH_P_LOCALTALK = 0x9 + ETH_P_LOOP = 0x60 + ETH_P_LOOPBACK = 0x9000 + ETH_P_MACSEC = 0x88e5 + ETH_P_MAP = 0xf9 + ETH_P_MOBITEX = 0x15 + ETH_P_MPLS_MC = 0x8848 + ETH_P_MPLS_UC = 0x8847 + ETH_P_MVRP = 0x88f5 + ETH_P_NCSI = 0x88f8 + ETH_P_NSH = 0x894f + ETH_P_PAE = 0x888e + ETH_P_PAUSE = 0x8808 + ETH_P_PHONET = 0xf5 + ETH_P_PPPTALK = 0x10 + ETH_P_PPP_DISC = 0x8863 + ETH_P_PPP_MP = 0x8 + ETH_P_PPP_SES = 0x8864 + ETH_P_PREAUTH = 0x88c7 + ETH_P_PRP = 0x88fb + ETH_P_PUP = 0x200 + ETH_P_PUPAT = 0x201 + ETH_P_QINQ1 = 0x9100 + ETH_P_QINQ2 = 0x9200 + ETH_P_QINQ3 = 0x9300 + ETH_P_RARP = 0x8035 + ETH_P_SCA = 0x6007 + ETH_P_SLOW = 0x8809 + ETH_P_SNAP = 0x5 + ETH_P_TDLS = 0x890d + ETH_P_TEB = 0x6558 + ETH_P_TIPC = 0x88ca + ETH_P_TRAILER = 0x1c + ETH_P_TR_802_2 = 0x11 + ETH_P_TSN = 0x22f0 + ETH_P_WAN_PPP = 0x7 + ETH_P_WCCP = 0x883e + ETH_P_X25 = 0x805 + ETH_P_XDSA = 0xf8 + EXABYTE_ENABLE_NEST = 0xf0 + EXT2_SUPER_MAGIC = 0xef53 + EXT3_SUPER_MAGIC = 0xef53 + EXT4_SUPER_MAGIC = 0xef53 + EXTA = 0xe + EXTB = 0xf + EXTPROC = 0x10000 + F2FS_SUPER_MAGIC = 0xf2f52010 + FALLOC_FL_COLLAPSE_RANGE = 0x8 + FALLOC_FL_INSERT_RANGE = 0x20 + FALLOC_FL_KEEP_SIZE = 0x1 + FALLOC_FL_NO_HIDE_STALE = 0x4 + FALLOC_FL_PUNCH_HOLE = 0x2 + FALLOC_FL_UNSHARE_RANGE = 0x40 + FALLOC_FL_ZERO_RANGE = 0x10 + FD_CLOEXEC = 0x1 + FD_SETSIZE = 0x400 + FF0 = 0x0 + FF1 = 0x8000 + FFDLY = 0x8000 + FLUSHO = 0x1000 + FS_ENCRYPTION_MODE_AES_128_CBC = 0x5 + FS_ENCRYPTION_MODE_AES_128_CTS = 0x6 + FS_ENCRYPTION_MODE_AES_256_CBC = 0x3 + FS_ENCRYPTION_MODE_AES_256_CTS = 0x4 + FS_ENCRYPTION_MODE_AES_256_GCM = 0x2 + FS_ENCRYPTION_MODE_AES_256_XTS = 0x1 + FS_ENCRYPTION_MODE_INVALID = 0x0 + FS_ENCRYPTION_MODE_SPECK128_256_CTS = 0x8 + FS_ENCRYPTION_MODE_SPECK128_256_XTS = 0x7 + FS_IOC_GET_ENCRYPTION_POLICY = 0x400c6615 + FS_IOC_GET_ENCRYPTION_PWSALT = 0x40106614 + FS_IOC_SET_ENCRYPTION_POLICY = 0x800c6613 + FS_KEY_DESCRIPTOR_SIZE = 0x8 + FS_KEY_DESC_PREFIX = "fscrypt:" + FS_KEY_DESC_PREFIX_SIZE = 0x8 + FS_MAX_KEY_SIZE = 0x40 + FS_POLICY_FLAGS_PAD_16 = 0x2 + FS_POLICY_FLAGS_PAD_32 = 0x3 + FS_POLICY_FLAGS_PAD_4 = 0x0 + FS_POLICY_FLAGS_PAD_8 = 0x1 + FS_POLICY_FLAGS_PAD_MASK = 0x3 + FS_POLICY_FLAGS_VALID = 0x3 + FUTEXFS_SUPER_MAGIC = 0xbad1dea + F_ADD_SEALS = 0x409 + F_DUPFD = 0x0 + F_DUPFD_CLOEXEC = 0x406 + F_EXLCK = 0x4 + F_GETFD = 0x1 + F_GETFL = 0x3 + F_GETLEASE = 0x401 + F_GETLK = 0x5 + F_GETLK64 = 0x5 + F_GETOWN = 0x9 + F_GETOWN_EX = 0x10 + F_GETPIPE_SZ = 0x408 + F_GETSIG = 0xb + F_GET_FILE_RW_HINT = 0x40d + F_GET_RW_HINT = 0x40b + F_GET_SEALS = 0x40a + F_LOCK = 0x1 + F_NOTIFY = 0x402 + F_OFD_GETLK = 0x24 + F_OFD_SETLK = 0x25 + F_OFD_SETLKW = 0x26 + F_OK = 0x0 + F_RDLCK = 0x0 + F_SEAL_GROW = 0x4 + F_SEAL_SEAL = 0x1 + F_SEAL_SHRINK = 0x2 + F_SEAL_WRITE = 0x8 + F_SETFD = 0x2 + F_SETFL = 0x4 + F_SETLEASE = 0x400 + F_SETLK = 0x6 + F_SETLK64 = 0x6 + F_SETLKW = 0x7 + F_SETLKW64 = 0x7 + F_SETOWN = 0x8 + F_SETOWN_EX = 0xf + F_SETPIPE_SZ = 0x407 + F_SETSIG = 0xa + F_SET_FILE_RW_HINT = 0x40e + F_SET_RW_HINT = 0x40c + F_SHLCK = 0x8 + F_TEST = 0x3 + F_TLOCK = 0x2 + F_ULOCK = 0x0 + F_UNLCK = 0x2 + F_WRLCK = 0x1 + GENL_ADMIN_PERM = 0x1 + GENL_CMD_CAP_DO = 0x2 + GENL_CMD_CAP_DUMP = 0x4 + GENL_CMD_CAP_HASPOL = 0x8 + GENL_HDRLEN = 0x4 + GENL_ID_CTRL = 0x10 + GENL_ID_PMCRAID = 0x12 + GENL_ID_VFS_DQUOT = 0x11 + GENL_MAX_ID = 0x3ff + GENL_MIN_ID = 0x10 + GENL_NAMSIZ = 0x10 + GENL_START_ALLOC = 0x13 + GENL_UNS_ADMIN_PERM = 0x10 + GRND_NONBLOCK = 0x1 + GRND_RANDOM = 0x2 + HDIO_DRIVE_CMD = 0x31f + HDIO_DRIVE_CMD_AEB = 0x31e + HDIO_DRIVE_CMD_HDR_SIZE = 0x4 + HDIO_DRIVE_HOB_HDR_SIZE = 0x8 + HDIO_DRIVE_RESET = 0x31c + HDIO_DRIVE_TASK = 0x31e + HDIO_DRIVE_TASKFILE = 0x31d + HDIO_DRIVE_TASK_HDR_SIZE = 0x8 + HDIO_GETGEO = 0x301 + HDIO_GET_32BIT = 0x309 + HDIO_GET_ACOUSTIC = 0x30f + HDIO_GET_ADDRESS = 0x310 + HDIO_GET_BUSSTATE = 0x31a + HDIO_GET_DMA = 0x30b + HDIO_GET_IDENTITY = 0x30d + HDIO_GET_KEEPSETTINGS = 0x308 + HDIO_GET_MULTCOUNT = 0x304 + HDIO_GET_NICE = 0x30c + HDIO_GET_NOWERR = 0x30a + HDIO_GET_QDMA = 0x305 + HDIO_GET_UNMASKINTR = 0x302 + HDIO_GET_WCACHE = 0x30e + HDIO_OBSOLETE_IDENTITY = 0x307 + HDIO_SCAN_HWIF = 0x328 + HDIO_SET_32BIT = 0x324 + HDIO_SET_ACOUSTIC = 0x32c + HDIO_SET_ADDRESS = 0x32f + HDIO_SET_BUSSTATE = 0x32d + HDIO_SET_DMA = 0x326 + HDIO_SET_KEEPSETTINGS = 0x323 + HDIO_SET_MULTCOUNT = 0x321 + HDIO_SET_NICE = 0x329 + HDIO_SET_NOWERR = 0x325 + HDIO_SET_PIO_MODE = 0x327 + HDIO_SET_QDMA = 0x32e + HDIO_SET_UNMASKINTR = 0x322 + HDIO_SET_WCACHE = 0x32b + HDIO_SET_XFER = 0x306 + HDIO_TRISTATE_HWIF = 0x31b + HDIO_UNREGISTER_HWIF = 0x32a + HOSTFS_SUPER_MAGIC = 0xc0ffee + HPFS_SUPER_MAGIC = 0xf995e849 + HUGETLBFS_MAGIC = 0x958458f6 + HUPCL = 0x400 + IBSHIFT = 0x10 + ICANON = 0x2 + ICMPV6_FILTER = 0x1 + ICRNL = 0x100 + IEXTEN = 0x8000 + IFA_F_DADFAILED = 0x8 + IFA_F_DEPRECATED = 0x20 + IFA_F_HOMEADDRESS = 0x10 + IFA_F_MANAGETEMPADDR = 0x100 + IFA_F_MCAUTOJOIN = 0x400 + IFA_F_NODAD = 0x2 + IFA_F_NOPREFIXROUTE = 0x200 + IFA_F_OPTIMISTIC = 0x4 + IFA_F_PERMANENT = 0x80 + IFA_F_SECONDARY = 0x1 + IFA_F_STABLE_PRIVACY = 0x800 + IFA_F_TEMPORARY = 0x1 + IFA_F_TENTATIVE = 0x40 + IFA_MAX = 0x9 + IFF_ALLMULTI = 0x200 + IFF_ATTACH_QUEUE = 0x200 + IFF_AUTOMEDIA = 0x4000 + IFF_BROADCAST = 0x2 + IFF_DEBUG = 0x4 + IFF_DETACH_QUEUE = 0x400 + IFF_DORMANT = 0x20000 + IFF_DYNAMIC = 0x8000 + IFF_ECHO = 0x40000 + IFF_LOOPBACK = 0x8 + IFF_LOWER_UP = 0x10000 + IFF_MASTER = 0x400 + IFF_MULTICAST = 0x1000 + IFF_MULTI_QUEUE = 0x100 + IFF_NAPI = 0x10 + IFF_NAPI_FRAGS = 0x20 + IFF_NOARP = 0x80 + IFF_NOFILTER = 0x1000 + IFF_NOTRAILERS = 0x20 + IFF_NO_PI = 0x1000 + IFF_ONE_QUEUE = 0x2000 + IFF_PERSIST = 0x800 + IFF_POINTOPOINT = 0x10 + IFF_PORTSEL = 0x2000 + IFF_PROMISC = 0x100 + IFF_RUNNING = 0x40 + IFF_SLAVE = 0x800 + IFF_TAP = 0x2 + IFF_TUN = 0x1 + IFF_TUN_EXCL = 0x8000 + IFF_UP = 0x1 + IFF_VNET_HDR = 0x4000 + IFF_VOLATILE = 0x70c5a + IFNAMSIZ = 0x10 + IGNBRK = 0x1 + IGNCR = 0x80 + IGNPAR = 0x4 + IMAXBEL = 0x2000 + INLCR = 0x40 + INPCK = 0x10 + IN_ACCESS = 0x1 + IN_ALL_EVENTS = 0xfff + IN_ATTRIB = 0x4 + IN_CLASSA_HOST = 0xffffff + IN_CLASSA_MAX = 0x80 + IN_CLASSA_NET = 0xff000000 + IN_CLASSA_NSHIFT = 0x18 + IN_CLASSB_HOST = 0xffff + IN_CLASSB_MAX = 0x10000 + IN_CLASSB_NET = 0xffff0000 + IN_CLASSB_NSHIFT = 0x10 + IN_CLASSC_HOST = 0xff + IN_CLASSC_NET = 0xffffff00 + IN_CLASSC_NSHIFT = 0x8 + IN_CLOEXEC = 0x80000 + IN_CLOSE = 0x18 + IN_CLOSE_NOWRITE = 0x10 + IN_CLOSE_WRITE = 0x8 + IN_CREATE = 0x100 + IN_DELETE = 0x200 + IN_DELETE_SELF = 0x400 + IN_DONT_FOLLOW = 0x2000000 + IN_EXCL_UNLINK = 0x4000000 + IN_IGNORED = 0x8000 + IN_ISDIR = 0x40000000 + IN_LOOPBACKNET = 0x7f + IN_MASK_ADD = 0x20000000 + IN_MODIFY = 0x2 + IN_MOVE = 0xc0 + IN_MOVED_FROM = 0x40 + IN_MOVED_TO = 0x80 + IN_MOVE_SELF = 0x800 + IN_NONBLOCK = 0x800 + IN_ONESHOT = 0x80000000 + IN_ONLYDIR = 0x1000000 + IN_OPEN = 0x20 + IN_Q_OVERFLOW = 0x4000 + IN_UNMOUNT = 0x2000 + IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x7b9 + IPPROTO_AH = 0x33 + IPPROTO_BEETPH = 0x5e + IPPROTO_COMP = 0x6c + IPPROTO_DCCP = 0x21 + IPPROTO_DSTOPTS = 0x3c + IPPROTO_EGP = 0x8 + IPPROTO_ENCAP = 0x62 + IPPROTO_ESP = 0x32 + IPPROTO_FRAGMENT = 0x2c + IPPROTO_GRE = 0x2f + IPPROTO_HOPOPTS = 0x0 + IPPROTO_ICMP = 0x1 + IPPROTO_ICMPV6 = 0x3a + IPPROTO_IDP = 0x16 + IPPROTO_IGMP = 0x2 + IPPROTO_IP = 0x0 + IPPROTO_IPIP = 0x4 + IPPROTO_IPV6 = 0x29 + IPPROTO_MH = 0x87 + IPPROTO_MPLS = 0x89 + IPPROTO_MTP = 0x5c + IPPROTO_NONE = 0x3b + IPPROTO_PIM = 0x67 + IPPROTO_PUP = 0xc + IPPROTO_RAW = 0xff + IPPROTO_ROUTING = 0x2b + IPPROTO_RSVP = 0x2e + IPPROTO_SCTP = 0x84 + IPPROTO_TCP = 0x6 + IPPROTO_TP = 0x1d + IPPROTO_UDP = 0x11 + IPPROTO_UDPLITE = 0x88 + IPV6_2292DSTOPTS = 0x4 + IPV6_2292HOPLIMIT = 0x8 + IPV6_2292HOPOPTS = 0x3 + IPV6_2292PKTINFO = 0x2 + IPV6_2292PKTOPTIONS = 0x6 + IPV6_2292RTHDR = 0x5 + IPV6_ADDRFORM = 0x1 + IPV6_ADDR_PREFERENCES = 0x48 + IPV6_ADD_MEMBERSHIP = 0x14 + IPV6_AUTHHDR = 0xa + IPV6_AUTOFLOWLABEL = 0x46 + IPV6_CHECKSUM = 0x7 + IPV6_DONTFRAG = 0x3e + IPV6_DROP_MEMBERSHIP = 0x15 + IPV6_DSTOPTS = 0x3b + IPV6_FREEBIND = 0x4e + IPV6_HDRINCL = 0x24 + IPV6_HOPLIMIT = 0x34 + IPV6_HOPOPTS = 0x36 + IPV6_IPSEC_POLICY = 0x22 + IPV6_JOIN_ANYCAST = 0x1b + IPV6_JOIN_GROUP = 0x14 + IPV6_LEAVE_ANYCAST = 0x1c + IPV6_LEAVE_GROUP = 0x15 + IPV6_MINHOPCOUNT = 0x49 + IPV6_MTU = 0x18 + IPV6_MTU_DISCOVER = 0x17 + IPV6_MULTICAST_HOPS = 0x12 + IPV6_MULTICAST_IF = 0x11 + IPV6_MULTICAST_LOOP = 0x13 + IPV6_NEXTHOP = 0x9 + IPV6_ORIGDSTADDR = 0x4a + IPV6_PATHMTU = 0x3d + IPV6_PKTINFO = 0x32 + IPV6_PMTUDISC_DO = 0x2 + IPV6_PMTUDISC_DONT = 0x0 + IPV6_PMTUDISC_INTERFACE = 0x4 + IPV6_PMTUDISC_OMIT = 0x5 + IPV6_PMTUDISC_PROBE = 0x3 + IPV6_PMTUDISC_WANT = 0x1 + IPV6_RECVDSTOPTS = 0x3a + IPV6_RECVERR = 0x19 + IPV6_RECVFRAGSIZE = 0x4d + IPV6_RECVHOPLIMIT = 0x33 + IPV6_RECVHOPOPTS = 0x35 + IPV6_RECVORIGDSTADDR = 0x4a + IPV6_RECVPATHMTU = 0x3c + IPV6_RECVPKTINFO = 0x31 + IPV6_RECVRTHDR = 0x38 + IPV6_RECVTCLASS = 0x42 + IPV6_ROUTER_ALERT = 0x16 + IPV6_RTHDR = 0x39 + IPV6_RTHDRDSTOPTS = 0x37 + IPV6_RTHDR_LOOSE = 0x0 + IPV6_RTHDR_STRICT = 0x1 + IPV6_RTHDR_TYPE_0 = 0x0 + IPV6_RXDSTOPTS = 0x3b + IPV6_RXHOPOPTS = 0x36 + IPV6_TCLASS = 0x43 + IPV6_TRANSPARENT = 0x4b + IPV6_UNICAST_HOPS = 0x10 + IPV6_UNICAST_IF = 0x4c + IPV6_V6ONLY = 0x1a + IPV6_XFRM_POLICY = 0x23 + IP_ADD_MEMBERSHIP = 0x23 + IP_ADD_SOURCE_MEMBERSHIP = 0x27 + IP_BIND_ADDRESS_NO_PORT = 0x18 + IP_BLOCK_SOURCE = 0x26 + IP_CHECKSUM = 0x17 + IP_DEFAULT_MULTICAST_LOOP = 0x1 + IP_DEFAULT_MULTICAST_TTL = 0x1 + IP_DF = 0x4000 + IP_DROP_MEMBERSHIP = 0x24 + IP_DROP_SOURCE_MEMBERSHIP = 0x28 + IP_FREEBIND = 0xf + IP_HDRINCL = 0x3 + IP_IPSEC_POLICY = 0x10 + IP_MAXPACKET = 0xffff + IP_MAX_MEMBERSHIPS = 0x14 + IP_MF = 0x2000 + IP_MINTTL = 0x15 + IP_MSFILTER = 0x29 + IP_MSS = 0x240 + IP_MTU = 0xe + IP_MTU_DISCOVER = 0xa + IP_MULTICAST_ALL = 0x31 + IP_MULTICAST_IF = 0x20 + IP_MULTICAST_LOOP = 0x22 + IP_MULTICAST_TTL = 0x21 + IP_NODEFRAG = 0x16 + IP_OFFMASK = 0x1fff + IP_OPTIONS = 0x4 + IP_ORIGDSTADDR = 0x14 + IP_PASSSEC = 0x12 + IP_PKTINFO = 0x8 + IP_PKTOPTIONS = 0x9 + IP_PMTUDISC = 0xa + IP_PMTUDISC_DO = 0x2 + IP_PMTUDISC_DONT = 0x0 + IP_PMTUDISC_INTERFACE = 0x4 + IP_PMTUDISC_OMIT = 0x5 + IP_PMTUDISC_PROBE = 0x3 + IP_PMTUDISC_WANT = 0x1 + IP_RECVERR = 0xb + IP_RECVFRAGSIZE = 0x19 + IP_RECVOPTS = 0x6 + IP_RECVORIGDSTADDR = 0x14 + IP_RECVRETOPTS = 0x7 + IP_RECVTOS = 0xd + IP_RECVTTL = 0xc + IP_RETOPTS = 0x7 + IP_RF = 0x8000 + IP_ROUTER_ALERT = 0x5 + IP_TOS = 0x1 + IP_TRANSPARENT = 0x13 + IP_TTL = 0x2 + IP_UNBLOCK_SOURCE = 0x25 + IP_UNICAST_IF = 0x32 + IP_XFRM_POLICY = 0x11 + ISIG = 0x1 + ISOFS_SUPER_MAGIC = 0x9660 + ISTRIP = 0x20 + IUCLC = 0x200 + IUTF8 = 0x4000 + IXANY = 0x800 + IXOFF = 0x1000 + IXON = 0x400 + JFFS2_SUPER_MAGIC = 0x72b6 + KEYCTL_ASSUME_AUTHORITY = 0x10 + KEYCTL_CHOWN = 0x4 + KEYCTL_CLEAR = 0x7 + KEYCTL_DESCRIBE = 0x6 + KEYCTL_DH_COMPUTE = 0x17 + KEYCTL_GET_KEYRING_ID = 0x0 + KEYCTL_GET_PERSISTENT = 0x16 + KEYCTL_GET_SECURITY = 0x11 + KEYCTL_INSTANTIATE = 0xc + KEYCTL_INSTANTIATE_IOV = 0x14 + KEYCTL_INVALIDATE = 0x15 + KEYCTL_JOIN_SESSION_KEYRING = 0x1 + KEYCTL_LINK = 0x8 + KEYCTL_NEGATE = 0xd + KEYCTL_READ = 0xb + KEYCTL_REJECT = 0x13 + KEYCTL_RESTRICT_KEYRING = 0x1d + KEYCTL_REVOKE = 0x3 + KEYCTL_SEARCH = 0xa + KEYCTL_SESSION_TO_PARENT = 0x12 + KEYCTL_SETPERM = 0x5 + KEYCTL_SET_REQKEY_KEYRING = 0xe + KEYCTL_SET_TIMEOUT = 0xf + KEYCTL_UNLINK = 0x9 + KEYCTL_UPDATE = 0x2 + KEY_REQKEY_DEFL_DEFAULT = 0x0 + KEY_REQKEY_DEFL_GROUP_KEYRING = 0x6 + KEY_REQKEY_DEFL_NO_CHANGE = -0x1 + KEY_REQKEY_DEFL_PROCESS_KEYRING = 0x2 + KEY_REQKEY_DEFL_REQUESTOR_KEYRING = 0x7 + KEY_REQKEY_DEFL_SESSION_KEYRING = 0x3 + KEY_REQKEY_DEFL_THREAD_KEYRING = 0x1 + KEY_REQKEY_DEFL_USER_KEYRING = 0x4 + KEY_REQKEY_DEFL_USER_SESSION_KEYRING = 0x5 + KEY_SPEC_GROUP_KEYRING = -0x6 + KEY_SPEC_PROCESS_KEYRING = -0x2 + KEY_SPEC_REQKEY_AUTH_KEY = -0x7 + KEY_SPEC_REQUESTOR_KEYRING = -0x8 + KEY_SPEC_SESSION_KEYRING = -0x3 + KEY_SPEC_THREAD_KEYRING = -0x1 + KEY_SPEC_USER_KEYRING = -0x4 + KEY_SPEC_USER_SESSION_KEYRING = -0x5 + LINUX_REBOOT_CMD_CAD_OFF = 0x0 + LINUX_REBOOT_CMD_CAD_ON = 0x89abcdef + LINUX_REBOOT_CMD_HALT = 0xcdef0123 + LINUX_REBOOT_CMD_KEXEC = 0x45584543 + LINUX_REBOOT_CMD_POWER_OFF = 0x4321fedc + LINUX_REBOOT_CMD_RESTART = 0x1234567 + LINUX_REBOOT_CMD_RESTART2 = 0xa1b2c3d4 + LINUX_REBOOT_CMD_SW_SUSPEND = 0xd000fce2 + LINUX_REBOOT_MAGIC1 = 0xfee1dead + LINUX_REBOOT_MAGIC2 = 0x28121969 + LOCK_EX = 0x2 + LOCK_NB = 0x4 + LOCK_SH = 0x1 + LOCK_UN = 0x8 + MADV_DODUMP = 0x11 + MADV_DOFORK = 0xb + MADV_DONTDUMP = 0x10 + MADV_DONTFORK = 0xa + MADV_DONTNEED = 0x4 + MADV_FREE = 0x8 + MADV_HUGEPAGE = 0xe + MADV_HWPOISON = 0x64 + MADV_KEEPONFORK = 0x13 + MADV_MERGEABLE = 0xc + MADV_NOHUGEPAGE = 0xf + MADV_NORMAL = 0x0 + MADV_RANDOM = 0x1 + MADV_REMOVE = 0x9 + MADV_SEQUENTIAL = 0x2 + MADV_UNMERGEABLE = 0xd + MADV_WILLNEED = 0x3 + MADV_WIPEONFORK = 0x12 + MAP_ANON = 0x20 + MAP_ANONYMOUS = 0x20 + MAP_DENYWRITE = 0x800 + MAP_EXECUTABLE = 0x1000 + MAP_FILE = 0x0 + MAP_FIXED = 0x10 + MAP_FIXED_NOREPLACE = 0x100000 + MAP_GROWSDOWN = 0x100 + MAP_HUGETLB = 0x40000 + MAP_HUGE_MASK = 0x3f + MAP_HUGE_SHIFT = 0x1a + MAP_LOCKED = 0x2000 + MAP_NONBLOCK = 0x10000 + MAP_NORESERVE = 0x4000 + MAP_POPULATE = 0x8000 + MAP_PRIVATE = 0x2 + MAP_SHARED = 0x1 + MAP_SHARED_VALIDATE = 0x3 + MAP_STACK = 0x20000 + MAP_SYNC = 0x80000 + MAP_TYPE = 0xf + MCL_CURRENT = 0x1 + MCL_FUTURE = 0x2 + MCL_ONFAULT = 0x4 + MINIX2_SUPER_MAGIC = 0x2468 + MINIX2_SUPER_MAGIC2 = 0x2478 + MINIX3_SUPER_MAGIC = 0x4d5a + MINIX_SUPER_MAGIC = 0x137f + MINIX_SUPER_MAGIC2 = 0x138f + MNT_DETACH = 0x2 + MNT_EXPIRE = 0x4 + MNT_FORCE = 0x1 + MSDOS_SUPER_MAGIC = 0x4d44 + MSG_BATCH = 0x40000 + MSG_CMSG_CLOEXEC = 0x40000000 + MSG_CONFIRM = 0x800 + MSG_CTRUNC = 0x8 + MSG_DONTROUTE = 0x4 + MSG_DONTWAIT = 0x40 + MSG_EOR = 0x80 + MSG_ERRQUEUE = 0x2000 + MSG_FASTOPEN = 0x20000000 + MSG_FIN = 0x200 + MSG_MORE = 0x8000 + MSG_NOSIGNAL = 0x4000 + MSG_OOB = 0x1 + MSG_PEEK = 0x2 + MSG_PROXY = 0x10 + MSG_RST = 0x1000 + MSG_SYN = 0x400 + MSG_TRUNC = 0x20 + MSG_TRYHARD = 0x4 + MSG_WAITALL = 0x100 + MSG_WAITFORONE = 0x10000 + MSG_ZEROCOPY = 0x4000000 + MS_ACTIVE = 0x40000000 + MS_ASYNC = 0x1 + MS_BIND = 0x1000 + MS_BORN = 0x20000000 + MS_DIRSYNC = 0x80 + MS_INVALIDATE = 0x2 + MS_I_VERSION = 0x800000 + MS_KERNMOUNT = 0x400000 + MS_LAZYTIME = 0x2000000 + MS_MANDLOCK = 0x40 + MS_MGC_MSK = 0xffff0000 + MS_MGC_VAL = 0xc0ed0000 + MS_MOVE = 0x2000 + MS_NOATIME = 0x400 + MS_NODEV = 0x4 + MS_NODIRATIME = 0x800 + MS_NOEXEC = 0x8 + MS_NOREMOTELOCK = 0x8000000 + MS_NOSEC = 0x10000000 + MS_NOSUID = 0x2 + MS_NOUSER = -0x80000000 + MS_POSIXACL = 0x10000 + MS_PRIVATE = 0x40000 + MS_RDONLY = 0x1 + MS_REC = 0x4000 + MS_RELATIME = 0x200000 + MS_REMOUNT = 0x20 + MS_RMT_MASK = 0x2800051 + MS_SHARED = 0x100000 + MS_SILENT = 0x8000 + MS_SLAVE = 0x80000 + MS_STRICTATIME = 0x1000000 + MS_SUBMOUNT = 0x4000000 + MS_SYNC = 0x4 + MS_SYNCHRONOUS = 0x10 + MS_UNBINDABLE = 0x20000 + MS_VERBOSE = 0x8000 + MTD_INODE_FS_MAGIC = 0x11307854 + NAME_MAX = 0xff + NCP_SUPER_MAGIC = 0x564c + NETLINK_ADD_MEMBERSHIP = 0x1 + NETLINK_AUDIT = 0x9 + NETLINK_BROADCAST_ERROR = 0x4 + NETLINK_CAP_ACK = 0xa + NETLINK_CONNECTOR = 0xb + NETLINK_CRYPTO = 0x15 + NETLINK_DNRTMSG = 0xe + NETLINK_DROP_MEMBERSHIP = 0x2 + NETLINK_ECRYPTFS = 0x13 + NETLINK_EXT_ACK = 0xb + NETLINK_FIB_LOOKUP = 0xa + NETLINK_FIREWALL = 0x3 + NETLINK_GENERIC = 0x10 + NETLINK_INET_DIAG = 0x4 + NETLINK_IP6_FW = 0xd + NETLINK_ISCSI = 0x8 + NETLINK_KOBJECT_UEVENT = 0xf + NETLINK_LISTEN_ALL_NSID = 0x8 + NETLINK_LIST_MEMBERSHIPS = 0x9 + NETLINK_NETFILTER = 0xc + NETLINK_NFLOG = 0x5 + NETLINK_NO_ENOBUFS = 0x5 + NETLINK_PKTINFO = 0x3 + NETLINK_RDMA = 0x14 + NETLINK_ROUTE = 0x0 + NETLINK_RX_RING = 0x6 + NETLINK_SCSITRANSPORT = 0x12 + NETLINK_SELINUX = 0x7 + NETLINK_SMC = 0x16 + NETLINK_SOCK_DIAG = 0x4 + NETLINK_TX_RING = 0x7 + NETLINK_UNUSED = 0x1 + NETLINK_USERSOCK = 0x2 + NETLINK_XFRM = 0x6 + NETNSA_MAX = 0x3 + NETNSA_NSID_NOT_ASSIGNED = -0x1 + NFNETLINK_V0 = 0x0 + NFNLGRP_ACCT_QUOTA = 0x8 + NFNLGRP_CONNTRACK_DESTROY = 0x3 + NFNLGRP_CONNTRACK_EXP_DESTROY = 0x6 + NFNLGRP_CONNTRACK_EXP_NEW = 0x4 + NFNLGRP_CONNTRACK_EXP_UPDATE = 0x5 + NFNLGRP_CONNTRACK_NEW = 0x1 + NFNLGRP_CONNTRACK_UPDATE = 0x2 + NFNLGRP_MAX = 0x9 + NFNLGRP_NFTABLES = 0x7 + NFNLGRP_NFTRACE = 0x9 + NFNLGRP_NONE = 0x0 + NFNL_BATCH_MAX = 0x1 + NFNL_MSG_BATCH_BEGIN = 0x10 + NFNL_MSG_BATCH_END = 0x11 + NFNL_NFA_NEST = 0x8000 + NFNL_SUBSYS_ACCT = 0x7 + NFNL_SUBSYS_COUNT = 0xc + NFNL_SUBSYS_CTHELPER = 0x9 + NFNL_SUBSYS_CTNETLINK = 0x1 + NFNL_SUBSYS_CTNETLINK_EXP = 0x2 + NFNL_SUBSYS_CTNETLINK_TIMEOUT = 0x8 + NFNL_SUBSYS_IPSET = 0x6 + NFNL_SUBSYS_NFTABLES = 0xa + NFNL_SUBSYS_NFT_COMPAT = 0xb + NFNL_SUBSYS_NONE = 0x0 + NFNL_SUBSYS_OSF = 0x5 + NFNL_SUBSYS_QUEUE = 0x3 + NFNL_SUBSYS_ULOG = 0x4 + NFS_SUPER_MAGIC = 0x6969 + NILFS_SUPER_MAGIC = 0x3434 + NL0 = 0x0 + NL1 = 0x100 + NLA_ALIGNTO = 0x4 + NLA_F_NESTED = 0x8000 + NLA_F_NET_BYTEORDER = 0x4000 + NLA_HDRLEN = 0x4 + NLDLY = 0x100 + NLMSG_ALIGNTO = 0x4 + NLMSG_DONE = 0x3 + NLMSG_ERROR = 0x2 + NLMSG_HDRLEN = 0x10 + NLMSG_MIN_TYPE = 0x10 + NLMSG_NOOP = 0x1 + NLMSG_OVERRUN = 0x4 + NLM_F_ACK = 0x4 + NLM_F_ACK_TLVS = 0x200 + NLM_F_APPEND = 0x800 + NLM_F_ATOMIC = 0x400 + NLM_F_CAPPED = 0x100 + NLM_F_CREATE = 0x400 + NLM_F_DUMP = 0x300 + NLM_F_DUMP_FILTERED = 0x20 + NLM_F_DUMP_INTR = 0x10 + NLM_F_ECHO = 0x8 + NLM_F_EXCL = 0x200 + NLM_F_MATCH = 0x200 + NLM_F_MULTI = 0x2 + NLM_F_NONREC = 0x100 + NLM_F_REPLACE = 0x100 + NLM_F_REQUEST = 0x1 + NLM_F_ROOT = 0x100 + NOFLSH = 0x80 + NSFS_MAGIC = 0x6e736673 + OCFS2_SUPER_MAGIC = 0x7461636f + OCRNL = 0x8 + OFDEL = 0x80 + OFILL = 0x40 + OLCUC = 0x2 + ONLCR = 0x4 + ONLRET = 0x20 + ONOCR = 0x10 + OPENPROM_SUPER_MAGIC = 0x9fa1 + OPOST = 0x1 + OVERLAYFS_SUPER_MAGIC = 0x794c7630 + O_ACCMODE = 0x3 + O_APPEND = 0x400 + O_ASYNC = 0x2000 + O_CLOEXEC = 0x80000 + O_CREAT = 0x40 + O_DIRECT = 0x4000 + O_DIRECTORY = 0x10000 + O_DSYNC = 0x1000 + O_EXCL = 0x80 + O_FSYNC = 0x101000 + O_LARGEFILE = 0x0 + O_NDELAY = 0x800 + O_NOATIME = 0x40000 + O_NOCTTY = 0x100 + O_NOFOLLOW = 0x20000 + O_NONBLOCK = 0x800 + O_PATH = 0x200000 + O_RDONLY = 0x0 + O_RDWR = 0x2 + O_RSYNC = 0x101000 + O_SYNC = 0x101000 + O_TMPFILE = 0x410000 + O_TRUNC = 0x200 + O_WRONLY = 0x1 + PACKET_ADD_MEMBERSHIP = 0x1 + PACKET_AUXDATA = 0x8 + PACKET_BROADCAST = 0x1 + PACKET_COPY_THRESH = 0x7 + PACKET_DROP_MEMBERSHIP = 0x2 + PACKET_FANOUT = 0x12 + PACKET_FANOUT_CBPF = 0x6 + PACKET_FANOUT_CPU = 0x2 + PACKET_FANOUT_DATA = 0x16 + PACKET_FANOUT_EBPF = 0x7 + PACKET_FANOUT_FLAG_DEFRAG = 0x8000 + PACKET_FANOUT_FLAG_ROLLOVER = 0x1000 + PACKET_FANOUT_FLAG_UNIQUEID = 0x2000 + PACKET_FANOUT_HASH = 0x0 + PACKET_FANOUT_LB = 0x1 + PACKET_FANOUT_QM = 0x5 + PACKET_FANOUT_RND = 0x4 + PACKET_FANOUT_ROLLOVER = 0x3 + PACKET_FASTROUTE = 0x6 + PACKET_HDRLEN = 0xb + PACKET_HOST = 0x0 + PACKET_KERNEL = 0x7 + PACKET_LOOPBACK = 0x5 + PACKET_LOSS = 0xe + PACKET_MR_ALLMULTI = 0x2 + PACKET_MR_MULTICAST = 0x0 + PACKET_MR_PROMISC = 0x1 + PACKET_MR_UNICAST = 0x3 + PACKET_MULTICAST = 0x2 + PACKET_ORIGDEV = 0x9 + PACKET_OTHERHOST = 0x3 + PACKET_OUTGOING = 0x4 + PACKET_QDISC_BYPASS = 0x14 + PACKET_RECV_OUTPUT = 0x3 + PACKET_RESERVE = 0xc + PACKET_ROLLOVER_STATS = 0x15 + PACKET_RX_RING = 0x5 + PACKET_STATISTICS = 0x6 + PACKET_TIMESTAMP = 0x11 + PACKET_TX_HAS_OFF = 0x13 + PACKET_TX_RING = 0xd + PACKET_TX_TIMESTAMP = 0x10 + PACKET_USER = 0x6 + PACKET_VERSION = 0xa + PACKET_VNET_HDR = 0xf + PARENB = 0x100 + PARITY_CRC16_PR0 = 0x2 + PARITY_CRC16_PR0_CCITT = 0x4 + PARITY_CRC16_PR1 = 0x3 + PARITY_CRC16_PR1_CCITT = 0x5 + PARITY_CRC32_PR0_CCITT = 0x6 + PARITY_CRC32_PR1_CCITT = 0x7 + PARITY_DEFAULT = 0x0 + PARITY_NONE = 0x1 + PARMRK = 0x8 + PARODD = 0x200 + PENDIN = 0x4000 + PERF_EVENT_IOC_DISABLE = 0x2401 + PERF_EVENT_IOC_ENABLE = 0x2400 + PERF_EVENT_IOC_ID = 0x80082407 + PERF_EVENT_IOC_MODIFY_ATTRIBUTES = 0x4008240b + PERF_EVENT_IOC_PAUSE_OUTPUT = 0x40042409 + PERF_EVENT_IOC_PERIOD = 0x40082404 + PERF_EVENT_IOC_QUERY_BPF = 0xc008240a + PERF_EVENT_IOC_REFRESH = 0x2402 + PERF_EVENT_IOC_RESET = 0x2403 + PERF_EVENT_IOC_SET_BPF = 0x40042408 + PERF_EVENT_IOC_SET_FILTER = 0x40082406 + PERF_EVENT_IOC_SET_OUTPUT = 0x2405 + PIPEFS_MAGIC = 0x50495045 + PRIO_PGRP = 0x1 + PRIO_PROCESS = 0x0 + PRIO_USER = 0x2 + PROC_SUPER_MAGIC = 0x9fa0 + PROT_EXEC = 0x4 + PROT_GROWSDOWN = 0x1000000 + PROT_GROWSUP = 0x2000000 + PROT_NONE = 0x0 + PROT_READ = 0x1 + PROT_WRITE = 0x2 + PR_CAPBSET_DROP = 0x18 + PR_CAPBSET_READ = 0x17 + PR_CAP_AMBIENT = 0x2f + PR_CAP_AMBIENT_CLEAR_ALL = 0x4 + PR_CAP_AMBIENT_IS_SET = 0x1 + PR_CAP_AMBIENT_LOWER = 0x3 + PR_CAP_AMBIENT_RAISE = 0x2 + PR_ENDIAN_BIG = 0x0 + PR_ENDIAN_LITTLE = 0x1 + PR_ENDIAN_PPC_LITTLE = 0x2 + PR_FPEMU_NOPRINT = 0x1 + PR_FPEMU_SIGFPE = 0x2 + PR_FP_EXC_ASYNC = 0x2 + PR_FP_EXC_DISABLED = 0x0 + PR_FP_EXC_DIV = 0x10000 + PR_FP_EXC_INV = 0x100000 + PR_FP_EXC_NONRECOV = 0x1 + PR_FP_EXC_OVF = 0x20000 + PR_FP_EXC_PRECISE = 0x3 + PR_FP_EXC_RES = 0x80000 + PR_FP_EXC_SW_ENABLE = 0x80 + PR_FP_EXC_UND = 0x40000 + PR_FP_MODE_FR = 0x1 + PR_FP_MODE_FRE = 0x2 + PR_GET_CHILD_SUBREAPER = 0x25 + PR_GET_DUMPABLE = 0x3 + PR_GET_ENDIAN = 0x13 + PR_GET_FPEMU = 0x9 + PR_GET_FPEXC = 0xb + PR_GET_FP_MODE = 0x2e + PR_GET_KEEPCAPS = 0x7 + PR_GET_NAME = 0x10 + PR_GET_NO_NEW_PRIVS = 0x27 + PR_GET_PDEATHSIG = 0x2 + PR_GET_SECCOMP = 0x15 + PR_GET_SECUREBITS = 0x1b + PR_GET_SPECULATION_CTRL = 0x34 + PR_GET_THP_DISABLE = 0x2a + PR_GET_TID_ADDRESS = 0x28 + PR_GET_TIMERSLACK = 0x1e + PR_GET_TIMING = 0xd + PR_GET_TSC = 0x19 + PR_GET_UNALIGN = 0x5 + PR_MCE_KILL = 0x21 + PR_MCE_KILL_CLEAR = 0x0 + PR_MCE_KILL_DEFAULT = 0x2 + PR_MCE_KILL_EARLY = 0x1 + PR_MCE_KILL_GET = 0x22 + PR_MCE_KILL_LATE = 0x0 + PR_MCE_KILL_SET = 0x1 + PR_MPX_DISABLE_MANAGEMENT = 0x2c + PR_MPX_ENABLE_MANAGEMENT = 0x2b + PR_SET_CHILD_SUBREAPER = 0x24 + PR_SET_DUMPABLE = 0x4 + PR_SET_ENDIAN = 0x14 + PR_SET_FPEMU = 0xa + PR_SET_FPEXC = 0xc + PR_SET_FP_MODE = 0x2d + PR_SET_KEEPCAPS = 0x8 + PR_SET_MM = 0x23 + PR_SET_MM_ARG_END = 0x9 + PR_SET_MM_ARG_START = 0x8 + PR_SET_MM_AUXV = 0xc + PR_SET_MM_BRK = 0x7 + PR_SET_MM_END_CODE = 0x2 + PR_SET_MM_END_DATA = 0x4 + PR_SET_MM_ENV_END = 0xb + PR_SET_MM_ENV_START = 0xa + PR_SET_MM_EXE_FILE = 0xd + PR_SET_MM_MAP = 0xe + PR_SET_MM_MAP_SIZE = 0xf + PR_SET_MM_START_BRK = 0x6 + PR_SET_MM_START_CODE = 0x1 + PR_SET_MM_START_DATA = 0x3 + PR_SET_MM_START_STACK = 0x5 + PR_SET_NAME = 0xf + PR_SET_NO_NEW_PRIVS = 0x26 + PR_SET_PDEATHSIG = 0x1 + PR_SET_PTRACER = 0x59616d61 + PR_SET_PTRACER_ANY = 0xffffffffffffffff + PR_SET_SECCOMP = 0x16 + PR_SET_SECUREBITS = 0x1c + PR_SET_SPECULATION_CTRL = 0x35 + PR_SET_THP_DISABLE = 0x29 + PR_SET_TIMERSLACK = 0x1d + PR_SET_TIMING = 0xe + PR_SET_TSC = 0x1a + PR_SET_UNALIGN = 0x6 + PR_SPEC_DISABLE = 0x4 + PR_SPEC_ENABLE = 0x2 + PR_SPEC_FORCE_DISABLE = 0x8 + PR_SPEC_NOT_AFFECTED = 0x0 + PR_SPEC_PRCTL = 0x1 + PR_SPEC_STORE_BYPASS = 0x0 + PR_SVE_GET_VL = 0x33 + PR_SVE_SET_VL = 0x32 + PR_SVE_SET_VL_ONEXEC = 0x40000 + PR_SVE_VL_INHERIT = 0x20000 + PR_SVE_VL_LEN_MASK = 0xffff + PR_TASK_PERF_EVENTS_DISABLE = 0x1f + PR_TASK_PERF_EVENTS_ENABLE = 0x20 + PR_TIMING_STATISTICAL = 0x0 + PR_TIMING_TIMESTAMP = 0x1 + PR_TSC_ENABLE = 0x1 + PR_TSC_SIGSEGV = 0x2 + PR_UNALIGN_NOPRINT = 0x1 + PR_UNALIGN_SIGBUS = 0x2 + PSTOREFS_MAGIC = 0x6165676c + PTRACE_ATTACH = 0x10 + PTRACE_CONT = 0x7 + PTRACE_DETACH = 0x11 + PTRACE_EVENT_CLONE = 0x3 + PTRACE_EVENT_EXEC = 0x4 + PTRACE_EVENT_EXIT = 0x6 + PTRACE_EVENT_FORK = 0x1 + PTRACE_EVENT_SECCOMP = 0x7 + PTRACE_EVENT_STOP = 0x80 + PTRACE_EVENT_VFORK = 0x2 + PTRACE_EVENT_VFORK_DONE = 0x5 + PTRACE_GETEVENTMSG = 0x4201 + PTRACE_GETREGS = 0xc + PTRACE_GETREGSET = 0x4204 + PTRACE_GETSIGINFO = 0x4202 + PTRACE_GETSIGMASK = 0x420a + PTRACE_INTERRUPT = 0x4207 + PTRACE_KILL = 0x8 + PTRACE_LISTEN = 0x4208 + PTRACE_O_EXITKILL = 0x100000 + PTRACE_O_MASK = 0x3000ff + PTRACE_O_SUSPEND_SECCOMP = 0x200000 + PTRACE_O_TRACECLONE = 0x8 + PTRACE_O_TRACEEXEC = 0x10 + PTRACE_O_TRACEEXIT = 0x40 + PTRACE_O_TRACEFORK = 0x2 + PTRACE_O_TRACESECCOMP = 0x80 + PTRACE_O_TRACESYSGOOD = 0x1 + PTRACE_O_TRACEVFORK = 0x4 + PTRACE_O_TRACEVFORKDONE = 0x20 + PTRACE_PEEKDATA = 0x2 + PTRACE_PEEKSIGINFO = 0x4209 + PTRACE_PEEKSIGINFO_SHARED = 0x1 + PTRACE_PEEKTEXT = 0x1 + PTRACE_PEEKUSR = 0x3 + PTRACE_POKEDATA = 0x5 + PTRACE_POKETEXT = 0x4 + PTRACE_POKEUSR = 0x6 + PTRACE_SECCOMP_GET_FILTER = 0x420c + PTRACE_SECCOMP_GET_METADATA = 0x420d + PTRACE_SEIZE = 0x4206 + PTRACE_SETOPTIONS = 0x4200 + PTRACE_SETREGS = 0xd + PTRACE_SETREGSET = 0x4205 + PTRACE_SETSIGINFO = 0x4203 + PTRACE_SETSIGMASK = 0x420b + PTRACE_SINGLESTEP = 0x9 + PTRACE_SYSCALL = 0x18 + PTRACE_TRACEME = 0x0 + QNX4_SUPER_MAGIC = 0x2f + QNX6_SUPER_MAGIC = 0x68191122 + RAMFS_MAGIC = 0x858458f6 + RDTGROUP_SUPER_MAGIC = 0x7655821 + REISERFS_SUPER_MAGIC = 0x52654973 + RENAME_EXCHANGE = 0x2 + RENAME_NOREPLACE = 0x1 + RENAME_WHITEOUT = 0x4 + RLIMIT_AS = 0x9 + RLIMIT_CORE = 0x4 + RLIMIT_CPU = 0x0 + RLIMIT_DATA = 0x2 + RLIMIT_FSIZE = 0x1 + RLIMIT_LOCKS = 0xa + RLIMIT_MEMLOCK = 0x8 + RLIMIT_MSGQUEUE = 0xc + RLIMIT_NICE = 0xd + RLIMIT_NOFILE = 0x7 + RLIMIT_NPROC = 0x6 + RLIMIT_RSS = 0x5 + RLIMIT_RTPRIO = 0xe + RLIMIT_RTTIME = 0xf + RLIMIT_SIGPENDING = 0xb + RLIMIT_STACK = 0x3 + RLIM_INFINITY = 0xffffffffffffffff + RTAX_ADVMSS = 0x8 + RTAX_CC_ALGO = 0x10 + RTAX_CWND = 0x7 + RTAX_FASTOPEN_NO_COOKIE = 0x11 + RTAX_FEATURES = 0xc + RTAX_FEATURE_ALLFRAG = 0x8 + RTAX_FEATURE_ECN = 0x1 + RTAX_FEATURE_MASK = 0xf + RTAX_FEATURE_SACK = 0x2 + RTAX_FEATURE_TIMESTAMP = 0x4 + RTAX_HOPLIMIT = 0xa + RTAX_INITCWND = 0xb + RTAX_INITRWND = 0xe + RTAX_LOCK = 0x1 + RTAX_MAX = 0x11 + RTAX_MTU = 0x2 + RTAX_QUICKACK = 0xf + RTAX_REORDERING = 0x9 + RTAX_RTO_MIN = 0xd + RTAX_RTT = 0x4 + RTAX_RTTVAR = 0x5 + RTAX_SSTHRESH = 0x6 + RTAX_UNSPEC = 0x0 + RTAX_WINDOW = 0x3 + RTA_ALIGNTO = 0x4 + RTA_MAX = 0x1d + RTCF_DIRECTSRC = 0x4000000 + RTCF_DOREDIRECT = 0x1000000 + RTCF_LOG = 0x2000000 + RTCF_MASQ = 0x400000 + RTCF_NAT = 0x800000 + RTCF_VALVE = 0x200000 + RTC_AF = 0x20 + RTC_AIE_OFF = 0x7002 + RTC_AIE_ON = 0x7001 + RTC_ALM_READ = 0x80247008 + RTC_ALM_SET = 0x40247007 + RTC_EPOCH_READ = 0x8008700d + RTC_EPOCH_SET = 0x4008700e + RTC_IRQF = 0x80 + RTC_IRQP_READ = 0x8008700b + RTC_IRQP_SET = 0x4008700c + RTC_MAX_FREQ = 0x2000 + RTC_PF = 0x40 + RTC_PIE_OFF = 0x7006 + RTC_PIE_ON = 0x7005 + RTC_PLL_GET = 0x80207011 + RTC_PLL_SET = 0x40207012 + RTC_RD_TIME = 0x80247009 + RTC_SET_TIME = 0x4024700a + RTC_UF = 0x10 + RTC_UIE_OFF = 0x7004 + RTC_UIE_ON = 0x7003 + RTC_VL_CLR = 0x7014 + RTC_VL_READ = 0x80047013 + RTC_WIE_OFF = 0x7010 + RTC_WIE_ON = 0x700f + RTC_WKALM_RD = 0x80287010 + RTC_WKALM_SET = 0x4028700f + RTF_ADDRCLASSMASK = 0xf8000000 + RTF_ADDRCONF = 0x40000 + RTF_ALLONLINK = 0x20000 + RTF_BROADCAST = 0x10000000 + RTF_CACHE = 0x1000000 + RTF_DEFAULT = 0x10000 + RTF_DYNAMIC = 0x10 + RTF_FLOW = 0x2000000 + RTF_GATEWAY = 0x2 + RTF_HOST = 0x4 + RTF_INTERFACE = 0x40000000 + RTF_IRTT = 0x100 + RTF_LINKRT = 0x100000 + RTF_LOCAL = 0x80000000 + RTF_MODIFIED = 0x20 + RTF_MSS = 0x40 + RTF_MTU = 0x40 + RTF_MULTICAST = 0x20000000 + RTF_NAT = 0x8000000 + RTF_NOFORWARD = 0x1000 + RTF_NONEXTHOP = 0x200000 + RTF_NOPMTUDISC = 0x4000 + RTF_POLICY = 0x4000000 + RTF_REINSTATE = 0x8 + RTF_REJECT = 0x200 + RTF_STATIC = 0x400 + RTF_THROW = 0x2000 + RTF_UP = 0x1 + RTF_WINDOW = 0x80 + RTF_XRESOLVE = 0x800 + RTM_BASE = 0x10 + RTM_DELACTION = 0x31 + RTM_DELADDR = 0x15 + RTM_DELADDRLABEL = 0x49 + RTM_DELLINK = 0x11 + RTM_DELMDB = 0x55 + RTM_DELNEIGH = 0x1d + RTM_DELNETCONF = 0x51 + RTM_DELNSID = 0x59 + RTM_DELQDISC = 0x25 + RTM_DELROUTE = 0x19 + RTM_DELRULE = 0x21 + RTM_DELTCLASS = 0x29 + RTM_DELTFILTER = 0x2d + RTM_F_CLONED = 0x200 + RTM_F_EQUALIZE = 0x400 + RTM_F_FIB_MATCH = 0x2000 + RTM_F_LOOKUP_TABLE = 0x1000 + RTM_F_NOTIFY = 0x100 + RTM_F_PREFIX = 0x800 + RTM_GETACTION = 0x32 + RTM_GETADDR = 0x16 + RTM_GETADDRLABEL = 0x4a + RTM_GETANYCAST = 0x3e + RTM_GETDCB = 0x4e + RTM_GETLINK = 0x12 + RTM_GETMDB = 0x56 + RTM_GETMULTICAST = 0x3a + RTM_GETNEIGH = 0x1e + RTM_GETNEIGHTBL = 0x42 + RTM_GETNETCONF = 0x52 + RTM_GETNSID = 0x5a + RTM_GETQDISC = 0x26 + RTM_GETROUTE = 0x1a + RTM_GETRULE = 0x22 + RTM_GETSTATS = 0x5e + RTM_GETTCLASS = 0x2a + RTM_GETTFILTER = 0x2e + RTM_MAX = 0x63 + RTM_NEWACTION = 0x30 + RTM_NEWADDR = 0x14 + RTM_NEWADDRLABEL = 0x48 + RTM_NEWCACHEREPORT = 0x60 + RTM_NEWLINK = 0x10 + RTM_NEWMDB = 0x54 + RTM_NEWNDUSEROPT = 0x44 + RTM_NEWNEIGH = 0x1c + RTM_NEWNEIGHTBL = 0x40 + RTM_NEWNETCONF = 0x50 + RTM_NEWNSID = 0x58 + RTM_NEWPREFIX = 0x34 + RTM_NEWQDISC = 0x24 + RTM_NEWROUTE = 0x18 + RTM_NEWRULE = 0x20 + RTM_NEWSTATS = 0x5c + RTM_NEWTCLASS = 0x28 + RTM_NEWTFILTER = 0x2c + RTM_NR_FAMILIES = 0x15 + RTM_NR_MSGTYPES = 0x54 + RTM_SETDCB = 0x4f + RTM_SETLINK = 0x13 + RTM_SETNEIGHTBL = 0x43 + RTNH_ALIGNTO = 0x4 + RTNH_COMPARE_MASK = 0x19 + RTNH_F_DEAD = 0x1 + RTNH_F_LINKDOWN = 0x10 + RTNH_F_OFFLOAD = 0x8 + RTNH_F_ONLINK = 0x4 + RTNH_F_PERVASIVE = 0x2 + RTNH_F_UNRESOLVED = 0x20 + RTN_MAX = 0xb + RTPROT_BABEL = 0x2a + RTPROT_BGP = 0xba + RTPROT_BIRD = 0xc + RTPROT_BOOT = 0x3 + RTPROT_DHCP = 0x10 + RTPROT_DNROUTED = 0xd + RTPROT_EIGRP = 0xc0 + RTPROT_GATED = 0x8 + RTPROT_ISIS = 0xbb + RTPROT_KERNEL = 0x2 + RTPROT_MROUTED = 0x11 + RTPROT_MRT = 0xa + RTPROT_NTK = 0xf + RTPROT_OSPF = 0xbc + RTPROT_RA = 0x9 + RTPROT_REDIRECT = 0x1 + RTPROT_RIP = 0xbd + RTPROT_STATIC = 0x4 + RTPROT_UNSPEC = 0x0 + RTPROT_XORP = 0xe + RTPROT_ZEBRA = 0xb + RT_CLASS_DEFAULT = 0xfd + RT_CLASS_LOCAL = 0xff + RT_CLASS_MAIN = 0xfe + RT_CLASS_MAX = 0xff + RT_CLASS_UNSPEC = 0x0 + RUSAGE_CHILDREN = -0x1 + RUSAGE_SELF = 0x0 + RUSAGE_THREAD = 0x1 + SCM_CREDENTIALS = 0x2 + SCM_RIGHTS = 0x1 + SCM_TIMESTAMP = 0x1d + SCM_TIMESTAMPING = 0x25 + SCM_TIMESTAMPING_OPT_STATS = 0x36 + SCM_TIMESTAMPING_PKTINFO = 0x3a + SCM_TIMESTAMPNS = 0x23 + SCM_WIFI_STATUS = 0x29 + SECCOMP_MODE_DISABLED = 0x0 + SECCOMP_MODE_FILTER = 0x2 + SECCOMP_MODE_STRICT = 0x1 + SECURITYFS_MAGIC = 0x73636673 + SELINUX_MAGIC = 0xf97cff8c + SHUT_RD = 0x0 + SHUT_RDWR = 0x2 + SHUT_WR = 0x1 + SIOCADDDLCI = 0x8980 + SIOCADDMULTI = 0x8931 + SIOCADDRT = 0x890b + SIOCATMARK = 0x8905 + SIOCBONDCHANGEACTIVE = 0x8995 + SIOCBONDENSLAVE = 0x8990 + SIOCBONDINFOQUERY = 0x8994 + SIOCBONDRELEASE = 0x8991 + SIOCBONDSETHWADDR = 0x8992 + SIOCBONDSLAVEINFOQUERY = 0x8993 + SIOCBRADDBR = 0x89a0 + SIOCBRADDIF = 0x89a2 + SIOCBRDELBR = 0x89a1 + SIOCBRDELIF = 0x89a3 + SIOCDARP = 0x8953 + SIOCDELDLCI = 0x8981 + SIOCDELMULTI = 0x8932 + SIOCDELRT = 0x890c + SIOCDEVPRIVATE = 0x89f0 + SIOCDIFADDR = 0x8936 + SIOCDRARP = 0x8960 + SIOCETHTOOL = 0x8946 + SIOCGARP = 0x8954 + SIOCGHWTSTAMP = 0x89b1 + SIOCGIFADDR = 0x8915 + SIOCGIFBR = 0x8940 + SIOCGIFBRDADDR = 0x8919 + SIOCGIFCONF = 0x8912 + SIOCGIFCOUNT = 0x8938 + SIOCGIFDSTADDR = 0x8917 + SIOCGIFENCAP = 0x8925 + SIOCGIFFLAGS = 0x8913 + SIOCGIFHWADDR = 0x8927 + SIOCGIFINDEX = 0x8933 + SIOCGIFMAP = 0x8970 + SIOCGIFMEM = 0x891f + SIOCGIFMETRIC = 0x891d + SIOCGIFMTU = 0x8921 + SIOCGIFNAME = 0x8910 + SIOCGIFNETMASK = 0x891b + SIOCGIFPFLAGS = 0x8935 + SIOCGIFSLAVE = 0x8929 + SIOCGIFTXQLEN = 0x8942 + SIOCGIFVLAN = 0x8982 + SIOCGMIIPHY = 0x8947 + SIOCGMIIREG = 0x8948 + SIOCGPGRP = 0x8904 + SIOCGRARP = 0x8961 + SIOCGSKNS = 0x894c + SIOCGSTAMP = 0x8906 + SIOCGSTAMPNS = 0x8907 + SIOCINQ = 0x541b + SIOCOUTQ = 0x5411 + SIOCOUTQNSD = 0x894b + SIOCPROTOPRIVATE = 0x89e0 + SIOCRTMSG = 0x890d + SIOCSARP = 0x8955 + SIOCSHWTSTAMP = 0x89b0 + SIOCSIFADDR = 0x8916 + SIOCSIFBR = 0x8941 + SIOCSIFBRDADDR = 0x891a + SIOCSIFDSTADDR = 0x8918 + SIOCSIFENCAP = 0x8926 + SIOCSIFFLAGS = 0x8914 + SIOCSIFHWADDR = 0x8924 + SIOCSIFHWBROADCAST = 0x8937 + SIOCSIFLINK = 0x8911 + SIOCSIFMAP = 0x8971 + SIOCSIFMEM = 0x8920 + SIOCSIFMETRIC = 0x891e + SIOCSIFMTU = 0x8922 + SIOCSIFNAME = 0x8923 + SIOCSIFNETMASK = 0x891c + SIOCSIFPFLAGS = 0x8934 + SIOCSIFSLAVE = 0x8930 + SIOCSIFTXQLEN = 0x8943 + SIOCSIFVLAN = 0x8983 + SIOCSMIIREG = 0x8949 + SIOCSPGRP = 0x8902 + SIOCSRARP = 0x8962 + SIOCWANDEV = 0x894a + SMACK_MAGIC = 0x43415d53 + SMART_AUTOSAVE = 0xd2 + SMART_AUTO_OFFLINE = 0xdb + SMART_DISABLE = 0xd9 + SMART_ENABLE = 0xd8 + SMART_HCYL_PASS = 0xc2 + SMART_IMMEDIATE_OFFLINE = 0xd4 + SMART_LCYL_PASS = 0x4f + SMART_READ_LOG_SECTOR = 0xd5 + SMART_READ_THRESHOLDS = 0xd1 + SMART_READ_VALUES = 0xd0 + SMART_SAVE = 0xd3 + SMART_STATUS = 0xda + SMART_WRITE_LOG_SECTOR = 0xd6 + SMART_WRITE_THRESHOLDS = 0xd7 + SMB_SUPER_MAGIC = 0x517b + SOCKFS_MAGIC = 0x534f434b + SOCK_CLOEXEC = 0x80000 + SOCK_DCCP = 0x6 + SOCK_DGRAM = 0x2 + SOCK_IOC_TYPE = 0x89 + SOCK_NONBLOCK = 0x800 + SOCK_PACKET = 0xa + SOCK_RAW = 0x3 + SOCK_RDM = 0x4 + SOCK_SEQPACKET = 0x5 + SOCK_STREAM = 0x1 + SOL_AAL = 0x109 + SOL_ALG = 0x117 + SOL_ATM = 0x108 + SOL_CAIF = 0x116 + SOL_CAN_BASE = 0x64 + SOL_DCCP = 0x10d + SOL_DECNET = 0x105 + SOL_ICMPV6 = 0x3a + SOL_IP = 0x0 + SOL_IPV6 = 0x29 + SOL_IRDA = 0x10a + SOL_IUCV = 0x115 + SOL_KCM = 0x119 + SOL_LLC = 0x10c + SOL_NETBEUI = 0x10b + SOL_NETLINK = 0x10e + SOL_NFC = 0x118 + SOL_PACKET = 0x107 + SOL_PNPIPE = 0x113 + SOL_PPPOL2TP = 0x111 + SOL_RAW = 0xff + SOL_RDS = 0x114 + SOL_RXRPC = 0x110 + SOL_SOCKET = 0x1 + SOL_TCP = 0x6 + SOL_TIPC = 0x10f + SOL_TLS = 0x11a + SOL_X25 = 0x106 + SOMAXCONN = 0x80 + SO_ACCEPTCONN = 0x1e + SO_ATTACH_BPF = 0x32 + SO_ATTACH_FILTER = 0x1a + SO_ATTACH_REUSEPORT_CBPF = 0x33 + SO_ATTACH_REUSEPORT_EBPF = 0x34 + SO_BINDTODEVICE = 0x19 + SO_BPF_EXTENSIONS = 0x30 + SO_BROADCAST = 0x6 + SO_BSDCOMPAT = 0xe + SO_BUSY_POLL = 0x2e + SO_CNX_ADVICE = 0x35 + SO_COOKIE = 0x39 + SO_DEBUG = 0x1 + SO_DETACH_BPF = 0x1b + SO_DETACH_FILTER = 0x1b + SO_DOMAIN = 0x27 + SO_DONTROUTE = 0x5 + SO_ERROR = 0x4 + SO_GET_FILTER = 0x1a + SO_INCOMING_CPU = 0x31 + SO_INCOMING_NAPI_ID = 0x38 + SO_KEEPALIVE = 0x9 + SO_LINGER = 0xd + SO_LOCK_FILTER = 0x2c + SO_MARK = 0x24 + SO_MAX_PACING_RATE = 0x2f + SO_MEMINFO = 0x37 + SO_NOFCS = 0x2b + SO_NO_CHECK = 0xb + SO_OOBINLINE = 0xa + SO_PASSCRED = 0x10 + SO_PASSSEC = 0x22 + SO_PEEK_OFF = 0x2a + SO_PEERCRED = 0x11 + SO_PEERGROUPS = 0x3b + SO_PEERNAME = 0x1c + SO_PEERSEC = 0x1f + SO_PRIORITY = 0xc + SO_PROTOCOL = 0x26 + SO_RCVBUF = 0x8 + SO_RCVBUFFORCE = 0x21 + SO_RCVLOWAT = 0x12 + SO_RCVTIMEO = 0x14 + SO_REUSEADDR = 0x2 + SO_REUSEPORT = 0xf + SO_RXQ_OVFL = 0x28 + SO_SECURITY_AUTHENTICATION = 0x16 + SO_SECURITY_ENCRYPTION_NETWORK = 0x18 + SO_SECURITY_ENCRYPTION_TRANSPORT = 0x17 + SO_SELECT_ERR_QUEUE = 0x2d + SO_SNDBUF = 0x7 + SO_SNDBUFFORCE = 0x20 + SO_SNDLOWAT = 0x13 + SO_SNDTIMEO = 0x15 + SO_TIMESTAMP = 0x1d + SO_TIMESTAMPING = 0x25 + SO_TIMESTAMPNS = 0x23 + SO_TYPE = 0x3 + SO_VM_SOCKETS_BUFFER_MAX_SIZE = 0x2 + SO_VM_SOCKETS_BUFFER_MIN_SIZE = 0x1 + SO_VM_SOCKETS_BUFFER_SIZE = 0x0 + SO_VM_SOCKETS_CONNECT_TIMEOUT = 0x6 + SO_VM_SOCKETS_NONBLOCK_TXRX = 0x7 + SO_VM_SOCKETS_PEER_HOST_VM_ID = 0x3 + SO_VM_SOCKETS_TRUSTED = 0x5 + SO_WIFI_STATUS = 0x29 + SO_ZEROCOPY = 0x3c + SPLICE_F_GIFT = 0x8 + SPLICE_F_MORE = 0x4 + SPLICE_F_MOVE = 0x1 + SPLICE_F_NONBLOCK = 0x2 + SQUASHFS_MAGIC = 0x73717368 + STACK_END_MAGIC = 0x57ac6e9d + STATX_ALL = 0xfff + STATX_ATIME = 0x20 + STATX_ATTR_APPEND = 0x20 + STATX_ATTR_AUTOMOUNT = 0x1000 + STATX_ATTR_COMPRESSED = 0x4 + STATX_ATTR_ENCRYPTED = 0x800 + STATX_ATTR_IMMUTABLE = 0x10 + STATX_ATTR_NODUMP = 0x40 + STATX_BASIC_STATS = 0x7ff + STATX_BLOCKS = 0x400 + STATX_BTIME = 0x800 + STATX_CTIME = 0x80 + STATX_GID = 0x10 + STATX_INO = 0x100 + STATX_MODE = 0x2 + STATX_MTIME = 0x40 + STATX_NLINK = 0x4 + STATX_SIZE = 0x200 + STATX_TYPE = 0x1 + STATX_UID = 0x8 + STATX__RESERVED = 0x80000000 + SYNC_FILE_RANGE_WAIT_AFTER = 0x4 + SYNC_FILE_RANGE_WAIT_BEFORE = 0x1 + SYNC_FILE_RANGE_WRITE = 0x2 + SYSFS_MAGIC = 0x62656572 + S_BLKSIZE = 0x200 + S_IEXEC = 0x40 + S_IFBLK = 0x6000 + S_IFCHR = 0x2000 + S_IFDIR = 0x4000 + S_IFIFO = 0x1000 + S_IFLNK = 0xa000 + S_IFMT = 0xf000 + S_IFREG = 0x8000 + S_IFSOCK = 0xc000 + S_IREAD = 0x100 + S_IRGRP = 0x20 + S_IROTH = 0x4 + S_IRUSR = 0x100 + S_IRWXG = 0x38 + S_IRWXO = 0x7 + S_IRWXU = 0x1c0 + S_ISGID = 0x400 + S_ISUID = 0x800 + S_ISVTX = 0x200 + S_IWGRP = 0x10 + S_IWOTH = 0x2 + S_IWRITE = 0x80 + S_IWUSR = 0x80 + S_IXGRP = 0x8 + S_IXOTH = 0x1 + S_IXUSR = 0x40 + TAB0 = 0x0 + TAB1 = 0x800 + TAB2 = 0x1000 + TAB3 = 0x1800 + TABDLY = 0x1800 + TASKSTATS_CMD_ATTR_MAX = 0x4 + TASKSTATS_CMD_MAX = 0x2 + TASKSTATS_GENL_NAME = "TASKSTATS" + TASKSTATS_GENL_VERSION = 0x1 + TASKSTATS_TYPE_MAX = 0x6 + TASKSTATS_VERSION = 0x8 + TCFLSH = 0x540b + TCGETA = 0x5405 + TCGETS = 0x5401 + TCGETS2 = 0x802c542a + TCGETX = 0x5432 + TCIFLUSH = 0x0 + TCIOFF = 0x2 + TCIOFLUSH = 0x2 + TCION = 0x3 + TCOFLUSH = 0x1 + TCOOFF = 0x0 + TCOON = 0x1 + TCP_CC_INFO = 0x1a + TCP_CONGESTION = 0xd + TCP_COOKIE_IN_ALWAYS = 0x1 + TCP_COOKIE_MAX = 0x10 + TCP_COOKIE_MIN = 0x8 + TCP_COOKIE_OUT_NEVER = 0x2 + TCP_COOKIE_PAIR_SIZE = 0x20 + TCP_COOKIE_TRANSACTIONS = 0xf + TCP_CORK = 0x3 + TCP_DEFER_ACCEPT = 0x9 + TCP_FASTOPEN = 0x17 + TCP_FASTOPEN_CONNECT = 0x1e + TCP_FASTOPEN_KEY = 0x21 + TCP_FASTOPEN_NO_COOKIE = 0x22 + TCP_INFO = 0xb + TCP_KEEPCNT = 0x6 + TCP_KEEPIDLE = 0x4 + TCP_KEEPINTVL = 0x5 + TCP_LINGER2 = 0x8 + TCP_MAXSEG = 0x2 + TCP_MAXWIN = 0xffff + TCP_MAX_WINSHIFT = 0xe + TCP_MD5SIG = 0xe + TCP_MD5SIG_EXT = 0x20 + TCP_MD5SIG_FLAG_PREFIX = 0x1 + TCP_MD5SIG_MAXKEYLEN = 0x50 + TCP_MSS = 0x200 + TCP_MSS_DEFAULT = 0x218 + TCP_MSS_DESIRED = 0x4c4 + TCP_NODELAY = 0x1 + TCP_NOTSENT_LOWAT = 0x19 + TCP_QUEUE_SEQ = 0x15 + TCP_QUICKACK = 0xc + TCP_REPAIR = 0x13 + TCP_REPAIR_OPTIONS = 0x16 + TCP_REPAIR_QUEUE = 0x14 + TCP_REPAIR_WINDOW = 0x1d + TCP_SAVED_SYN = 0x1c + TCP_SAVE_SYN = 0x1b + TCP_SYNCNT = 0x7 + TCP_S_DATA_IN = 0x4 + TCP_S_DATA_OUT = 0x8 + TCP_THIN_DUPACK = 0x11 + TCP_THIN_LINEAR_TIMEOUTS = 0x10 + TCP_TIMESTAMP = 0x18 + TCP_ULP = 0x1f + TCP_USER_TIMEOUT = 0x12 + TCP_WINDOW_CLAMP = 0xa + TCSAFLUSH = 0x2 + TCSBRK = 0x5409 + TCSBRKP = 0x5425 + TCSETA = 0x5406 + TCSETAF = 0x5408 + TCSETAW = 0x5407 + TCSETS = 0x5402 + TCSETS2 = 0x402c542b + TCSETSF = 0x5404 + TCSETSF2 = 0x402c542d + TCSETSW = 0x5403 + TCSETSW2 = 0x402c542c + TCSETX = 0x5433 + TCSETXF = 0x5434 + TCSETXW = 0x5435 + TCXONC = 0x540a + TIOCCBRK = 0x5428 + TIOCCONS = 0x541d + TIOCEXCL = 0x540c + TIOCGDEV = 0x80045432 + TIOCGETD = 0x5424 + TIOCGEXCL = 0x80045440 + TIOCGICOUNT = 0x545d + TIOCGLCKTRMIOS = 0x5456 + TIOCGPGRP = 0x540f + TIOCGPKT = 0x80045438 + TIOCGPTLCK = 0x80045439 + TIOCGPTN = 0x80045430 + TIOCGPTPEER = 0x5441 + TIOCGRS485 = 0x542e + TIOCGSERIAL = 0x541e + TIOCGSID = 0x5429 + TIOCGSOFTCAR = 0x5419 + TIOCGWINSZ = 0x5413 + TIOCINQ = 0x541b + TIOCLINUX = 0x541c + TIOCMBIC = 0x5417 + TIOCMBIS = 0x5416 + TIOCMGET = 0x5415 + TIOCMIWAIT = 0x545c + TIOCMSET = 0x5418 + TIOCM_CAR = 0x40 + TIOCM_CD = 0x40 + TIOCM_CTS = 0x20 + TIOCM_DSR = 0x100 + TIOCM_DTR = 0x2 + TIOCM_LE = 0x1 + TIOCM_RI = 0x80 + TIOCM_RNG = 0x80 + TIOCM_RTS = 0x4 + TIOCM_SR = 0x10 + TIOCM_ST = 0x8 + TIOCNOTTY = 0x5422 + TIOCNXCL = 0x540d + TIOCOUTQ = 0x5411 + TIOCPKT = 0x5420 + TIOCPKT_DATA = 0x0 + TIOCPKT_DOSTOP = 0x20 + TIOCPKT_FLUSHREAD = 0x1 + TIOCPKT_FLUSHWRITE = 0x2 + TIOCPKT_IOCTL = 0x40 + TIOCPKT_NOSTOP = 0x10 + TIOCPKT_START = 0x8 + TIOCPKT_STOP = 0x4 + TIOCSBRK = 0x5427 + TIOCSCTTY = 0x540e + TIOCSERCONFIG = 0x5453 + TIOCSERGETLSR = 0x5459 + TIOCSERGETMULTI = 0x545a + TIOCSERGSTRUCT = 0x5458 + TIOCSERGWILD = 0x5454 + TIOCSERSETMULTI = 0x545b + TIOCSERSWILD = 0x5455 + TIOCSER_TEMT = 0x1 + TIOCSETD = 0x5423 + TIOCSIG = 0x40045436 + TIOCSLCKTRMIOS = 0x5457 + TIOCSPGRP = 0x5410 + TIOCSPTLCK = 0x40045431 + TIOCSRS485 = 0x542f + TIOCSSERIAL = 0x541f + TIOCSSOFTCAR = 0x541a + TIOCSTI = 0x5412 + TIOCSWINSZ = 0x5414 + TIOCVHANGUP = 0x5437 + TMPFS_MAGIC = 0x1021994 + TOSTOP = 0x100 + TPACKET_ALIGNMENT = 0x10 + TPACKET_HDRLEN = 0x34 + TP_STATUS_AVAILABLE = 0x0 + TP_STATUS_BLK_TMO = 0x20 + TP_STATUS_COPY = 0x2 + TP_STATUS_CSUMNOTREADY = 0x8 + TP_STATUS_CSUM_VALID = 0x80 + TP_STATUS_KERNEL = 0x0 + TP_STATUS_LOSING = 0x4 + TP_STATUS_SENDING = 0x2 + TP_STATUS_SEND_REQUEST = 0x1 + TP_STATUS_TS_RAW_HARDWARE = -0x80000000 + TP_STATUS_TS_SOFTWARE = 0x20000000 + TP_STATUS_TS_SYS_HARDWARE = 0x40000000 + TP_STATUS_USER = 0x1 + TP_STATUS_VLAN_TPID_VALID = 0x40 + TP_STATUS_VLAN_VALID = 0x10 + TP_STATUS_WRONG_FORMAT = 0x4 + TRACEFS_MAGIC = 0x74726163 + TS_COMM_LEN = 0x20 + TUNATTACHFILTER = 0x401054d5 + TUNDETACHFILTER = 0x401054d6 + TUNGETFEATURES = 0x800454cf + TUNGETFILTER = 0x801054db + TUNGETIFF = 0x800454d2 + TUNGETSNDBUF = 0x800454d3 + TUNGETVNETBE = 0x800454df + TUNGETVNETHDRSZ = 0x800454d7 + TUNGETVNETLE = 0x800454dd + TUNSETDEBUG = 0x400454c9 + TUNSETFILTEREBPF = 0x800454e1 + TUNSETGROUP = 0x400454ce + TUNSETIFF = 0x400454ca + TUNSETIFINDEX = 0x400454da + TUNSETLINK = 0x400454cd + TUNSETNOCSUM = 0x400454c8 + TUNSETOFFLOAD = 0x400454d0 + TUNSETOWNER = 0x400454cc + TUNSETPERSIST = 0x400454cb + TUNSETQUEUE = 0x400454d9 + TUNSETSNDBUF = 0x400454d4 + TUNSETSTEERINGEBPF = 0x800454e0 + TUNSETTXFILTER = 0x400454d1 + TUNSETVNETBE = 0x400454de + TUNSETVNETHDRSZ = 0x400454d8 + TUNSETVNETLE = 0x400454dc + UBI_IOCATT = 0x40186f40 + UBI_IOCDET = 0x40046f41 + UBI_IOCEBCH = 0x40044f02 + UBI_IOCEBER = 0x40044f01 + UBI_IOCEBISMAP = 0x80044f05 + UBI_IOCEBMAP = 0x40084f03 + UBI_IOCEBUNMAP = 0x40044f04 + UBI_IOCMKVOL = 0x40986f00 + UBI_IOCRMVOL = 0x40046f01 + UBI_IOCRNVOL = 0x51106f03 + UBI_IOCRSVOL = 0x400c6f02 + UBI_IOCSETVOLPROP = 0x40104f06 + UBI_IOCVOLCRBLK = 0x40804f07 + UBI_IOCVOLRMBLK = 0x4f08 + UBI_IOCVOLUP = 0x40084f00 + UDF_SUPER_MAGIC = 0x15013346 + UMOUNT_NOFOLLOW = 0x8 + USBDEVICE_SUPER_MAGIC = 0x9fa2 + UTIME_NOW = 0x3fffffff + UTIME_OMIT = 0x3ffffffe + V9FS_MAGIC = 0x1021997 + VDISCARD = 0xd + VEOF = 0x4 + VEOL = 0xb + VEOL2 = 0x10 + VERASE = 0x2 + VINTR = 0x0 + VKILL = 0x3 + VLNEXT = 0xf + VMADDR_CID_ANY = 0xffffffff + VMADDR_CID_HOST = 0x2 + VMADDR_CID_HYPERVISOR = 0x0 + VMADDR_CID_RESERVED = 0x1 + VMADDR_PORT_ANY = 0xffffffff + VMIN = 0x6 + VM_SOCKETS_INVALID_VERSION = 0xffffffff + VQUIT = 0x1 + VREPRINT = 0xc + VSTART = 0x8 + VSTOP = 0x9 + VSUSP = 0xa + VSWTC = 0x7 + VT0 = 0x0 + VT1 = 0x4000 + VTDLY = 0x4000 + VTIME = 0x5 + VWERASE = 0xe + WALL = 0x40000000 + WCLONE = 0x80000000 + WCONTINUED = 0x8 + WDIOC_GETBOOTSTATUS = 0x80045702 + WDIOC_GETPRETIMEOUT = 0x80045709 + WDIOC_GETSTATUS = 0x80045701 + WDIOC_GETSUPPORT = 0x80285700 + WDIOC_GETTEMP = 0x80045703 + WDIOC_GETTIMELEFT = 0x8004570a + WDIOC_GETTIMEOUT = 0x80045707 + WDIOC_KEEPALIVE = 0x80045705 + WDIOC_SETOPTIONS = 0x80045704 + WDIOC_SETPRETIMEOUT = 0xc0045708 + WDIOC_SETTIMEOUT = 0xc0045706 + WEXITED = 0x4 + WIN_ACKMEDIACHANGE = 0xdb + WIN_CHECKPOWERMODE1 = 0xe5 + WIN_CHECKPOWERMODE2 = 0x98 + WIN_DEVICE_RESET = 0x8 + WIN_DIAGNOSE = 0x90 + WIN_DOORLOCK = 0xde + WIN_DOORUNLOCK = 0xdf + WIN_DOWNLOAD_MICROCODE = 0x92 + WIN_FLUSH_CACHE = 0xe7 + WIN_FLUSH_CACHE_EXT = 0xea + WIN_FORMAT = 0x50 + WIN_GETMEDIASTATUS = 0xda + WIN_IDENTIFY = 0xec + WIN_IDENTIFY_DMA = 0xee + WIN_IDLEIMMEDIATE = 0xe1 + WIN_INIT = 0x60 + WIN_MEDIAEJECT = 0xed + WIN_MULTREAD = 0xc4 + WIN_MULTREAD_EXT = 0x29 + WIN_MULTWRITE = 0xc5 + WIN_MULTWRITE_EXT = 0x39 + WIN_NOP = 0x0 + WIN_PACKETCMD = 0xa0 + WIN_PIDENTIFY = 0xa1 + WIN_POSTBOOT = 0xdc + WIN_PREBOOT = 0xdd + WIN_QUEUED_SERVICE = 0xa2 + WIN_READ = 0x20 + WIN_READDMA = 0xc8 + WIN_READDMA_EXT = 0x25 + WIN_READDMA_ONCE = 0xc9 + WIN_READDMA_QUEUED = 0xc7 + WIN_READDMA_QUEUED_EXT = 0x26 + WIN_READ_BUFFER = 0xe4 + WIN_READ_EXT = 0x24 + WIN_READ_LONG = 0x22 + WIN_READ_LONG_ONCE = 0x23 + WIN_READ_NATIVE_MAX = 0xf8 + WIN_READ_NATIVE_MAX_EXT = 0x27 + WIN_READ_ONCE = 0x21 + WIN_RECAL = 0x10 + WIN_RESTORE = 0x10 + WIN_SECURITY_DISABLE = 0xf6 + WIN_SECURITY_ERASE_PREPARE = 0xf3 + WIN_SECURITY_ERASE_UNIT = 0xf4 + WIN_SECURITY_FREEZE_LOCK = 0xf5 + WIN_SECURITY_SET_PASS = 0xf1 + WIN_SECURITY_UNLOCK = 0xf2 + WIN_SEEK = 0x70 + WIN_SETFEATURES = 0xef + WIN_SETIDLE1 = 0xe3 + WIN_SETIDLE2 = 0x97 + WIN_SETMULT = 0xc6 + WIN_SET_MAX = 0xf9 + WIN_SET_MAX_EXT = 0x37 + WIN_SLEEPNOW1 = 0xe6 + WIN_SLEEPNOW2 = 0x99 + WIN_SMART = 0xb0 + WIN_SPECIFY = 0x91 + WIN_SRST = 0x8 + WIN_STANDBY = 0xe2 + WIN_STANDBY2 = 0x96 + WIN_STANDBYNOW1 = 0xe0 + WIN_STANDBYNOW2 = 0x94 + WIN_VERIFY = 0x40 + WIN_VERIFY_EXT = 0x42 + WIN_VERIFY_ONCE = 0x41 + WIN_WRITE = 0x30 + WIN_WRITEDMA = 0xca + WIN_WRITEDMA_EXT = 0x35 + WIN_WRITEDMA_ONCE = 0xcb + WIN_WRITEDMA_QUEUED = 0xcc + WIN_WRITEDMA_QUEUED_EXT = 0x36 + WIN_WRITE_BUFFER = 0xe8 + WIN_WRITE_EXT = 0x34 + WIN_WRITE_LONG = 0x32 + WIN_WRITE_LONG_ONCE = 0x33 + WIN_WRITE_ONCE = 0x31 + WIN_WRITE_SAME = 0xe9 + WIN_WRITE_VERIFY = 0x3c + WNOHANG = 0x1 + WNOTHREAD = 0x20000000 + WNOWAIT = 0x1000000 + WORDSIZE = 0x40 + WSTOPPED = 0x2 + WUNTRACED = 0x2 + XATTR_CREATE = 0x1 + XATTR_REPLACE = 0x2 + XCASE = 0x4 + XENFS_SUPER_MAGIC = 0xabba1974 + XTABS = 0x1800 + ZSMALLOC_MAGIC = 0x58295829 +) + +// Errors +const ( + E2BIG = syscall.Errno(0x7) + EACCES = syscall.Errno(0xd) + EADDRINUSE = syscall.Errno(0x62) + EADDRNOTAVAIL = syscall.Errno(0x63) + EADV = syscall.Errno(0x44) + EAFNOSUPPORT = syscall.Errno(0x61) + EAGAIN = syscall.Errno(0xb) + EALREADY = syscall.Errno(0x72) + EBADE = syscall.Errno(0x34) + EBADF = syscall.Errno(0x9) + EBADFD = syscall.Errno(0x4d) + EBADMSG = syscall.Errno(0x4a) + EBADR = syscall.Errno(0x35) + EBADRQC = syscall.Errno(0x38) + EBADSLT = syscall.Errno(0x39) + EBFONT = syscall.Errno(0x3b) + EBUSY = syscall.Errno(0x10) + ECANCELED = syscall.Errno(0x7d) + ECHILD = syscall.Errno(0xa) + ECHRNG = syscall.Errno(0x2c) + ECOMM = syscall.Errno(0x46) + ECONNABORTED = syscall.Errno(0x67) + ECONNREFUSED = syscall.Errno(0x6f) + ECONNRESET = syscall.Errno(0x68) + EDEADLK = syscall.Errno(0x23) + EDEADLOCK = syscall.Errno(0x23) + EDESTADDRREQ = syscall.Errno(0x59) + EDOM = syscall.Errno(0x21) + EDOTDOT = syscall.Errno(0x49) + EDQUOT = syscall.Errno(0x7a) + EEXIST = syscall.Errno(0x11) + EFAULT = syscall.Errno(0xe) + EFBIG = syscall.Errno(0x1b) + EHOSTDOWN = syscall.Errno(0x70) + EHOSTUNREACH = syscall.Errno(0x71) + EHWPOISON = syscall.Errno(0x85) + EIDRM = syscall.Errno(0x2b) + EILSEQ = syscall.Errno(0x54) + EINPROGRESS = syscall.Errno(0x73) + EINTR = syscall.Errno(0x4) + EINVAL = syscall.Errno(0x16) + EIO = syscall.Errno(0x5) + EISCONN = syscall.Errno(0x6a) + EISDIR = syscall.Errno(0x15) + EISNAM = syscall.Errno(0x78) + EKEYEXPIRED = syscall.Errno(0x7f) + EKEYREJECTED = syscall.Errno(0x81) + EKEYREVOKED = syscall.Errno(0x80) + EL2HLT = syscall.Errno(0x33) + EL2NSYNC = syscall.Errno(0x2d) + EL3HLT = syscall.Errno(0x2e) + EL3RST = syscall.Errno(0x2f) + ELIBACC = syscall.Errno(0x4f) + ELIBBAD = syscall.Errno(0x50) + ELIBEXEC = syscall.Errno(0x53) + ELIBMAX = syscall.Errno(0x52) + ELIBSCN = syscall.Errno(0x51) + ELNRNG = syscall.Errno(0x30) + ELOOP = syscall.Errno(0x28) + EMEDIUMTYPE = syscall.Errno(0x7c) + EMFILE = syscall.Errno(0x18) + EMLINK = syscall.Errno(0x1f) + EMSGSIZE = syscall.Errno(0x5a) + EMULTIHOP = syscall.Errno(0x48) + ENAMETOOLONG = syscall.Errno(0x24) + ENAVAIL = syscall.Errno(0x77) + ENETDOWN = syscall.Errno(0x64) + ENETRESET = syscall.Errno(0x66) + ENETUNREACH = syscall.Errno(0x65) + ENFILE = syscall.Errno(0x17) + ENOANO = syscall.Errno(0x37) + ENOBUFS = syscall.Errno(0x69) + ENOCSI = syscall.Errno(0x32) + ENODATA = syscall.Errno(0x3d) + ENODEV = syscall.Errno(0x13) + ENOENT = syscall.Errno(0x2) + ENOEXEC = syscall.Errno(0x8) + ENOKEY = syscall.Errno(0x7e) + ENOLCK = syscall.Errno(0x25) + ENOLINK = syscall.Errno(0x43) + ENOMEDIUM = syscall.Errno(0x7b) + ENOMEM = syscall.Errno(0xc) + ENOMSG = syscall.Errno(0x2a) + ENONET = syscall.Errno(0x40) + ENOPKG = syscall.Errno(0x41) + ENOPROTOOPT = syscall.Errno(0x5c) + ENOSPC = syscall.Errno(0x1c) + ENOSR = syscall.Errno(0x3f) + ENOSTR = syscall.Errno(0x3c) + ENOSYS = syscall.Errno(0x26) + ENOTBLK = syscall.Errno(0xf) + ENOTCONN = syscall.Errno(0x6b) + ENOTDIR = syscall.Errno(0x14) + ENOTEMPTY = syscall.Errno(0x27) + ENOTNAM = syscall.Errno(0x76) + ENOTRECOVERABLE = syscall.Errno(0x83) + ENOTSOCK = syscall.Errno(0x58) + ENOTSUP = syscall.Errno(0x5f) + ENOTTY = syscall.Errno(0x19) + ENOTUNIQ = syscall.Errno(0x4c) + ENXIO = syscall.Errno(0x6) + EOPNOTSUPP = syscall.Errno(0x5f) + EOVERFLOW = syscall.Errno(0x4b) + EOWNERDEAD = syscall.Errno(0x82) + EPERM = syscall.Errno(0x1) + EPFNOSUPPORT = syscall.Errno(0x60) + EPIPE = syscall.Errno(0x20) + EPROTO = syscall.Errno(0x47) + EPROTONOSUPPORT = syscall.Errno(0x5d) + EPROTOTYPE = syscall.Errno(0x5b) + ERANGE = syscall.Errno(0x22) + EREMCHG = syscall.Errno(0x4e) + EREMOTE = syscall.Errno(0x42) + EREMOTEIO = syscall.Errno(0x79) + ERESTART = syscall.Errno(0x55) + ERFKILL = syscall.Errno(0x84) + EROFS = syscall.Errno(0x1e) + ESHUTDOWN = syscall.Errno(0x6c) + ESOCKTNOSUPPORT = syscall.Errno(0x5e) + ESPIPE = syscall.Errno(0x1d) + ESRCH = syscall.Errno(0x3) + ESRMNT = syscall.Errno(0x45) + ESTALE = syscall.Errno(0x74) + ESTRPIPE = syscall.Errno(0x56) + ETIME = syscall.Errno(0x3e) + ETIMEDOUT = syscall.Errno(0x6e) + ETOOMANYREFS = syscall.Errno(0x6d) + ETXTBSY = syscall.Errno(0x1a) + EUCLEAN = syscall.Errno(0x75) + EUNATCH = syscall.Errno(0x31) + EUSERS = syscall.Errno(0x57) + EWOULDBLOCK = syscall.Errno(0xb) + EXDEV = syscall.Errno(0x12) + EXFULL = syscall.Errno(0x36) +) + +// Signals +const ( + SIGABRT = syscall.Signal(0x6) + SIGALRM = syscall.Signal(0xe) + SIGBUS = syscall.Signal(0x7) + SIGCHLD = syscall.Signal(0x11) + SIGCLD = syscall.Signal(0x11) + SIGCONT = syscall.Signal(0x12) + SIGFPE = syscall.Signal(0x8) + SIGHUP = syscall.Signal(0x1) + SIGILL = syscall.Signal(0x4) + SIGINT = syscall.Signal(0x2) + SIGIO = syscall.Signal(0x1d) + SIGIOT = syscall.Signal(0x6) + SIGKILL = syscall.Signal(0x9) + SIGPIPE = syscall.Signal(0xd) + SIGPOLL = syscall.Signal(0x1d) + SIGPROF = syscall.Signal(0x1b) + SIGPWR = syscall.Signal(0x1e) + SIGQUIT = syscall.Signal(0x3) + SIGSEGV = syscall.Signal(0xb) + SIGSTKFLT = syscall.Signal(0x10) + SIGSTOP = syscall.Signal(0x13) + SIGSYS = syscall.Signal(0x1f) + SIGTERM = syscall.Signal(0xf) + SIGTRAP = syscall.Signal(0x5) + SIGTSTP = syscall.Signal(0x14) + SIGTTIN = syscall.Signal(0x15) + SIGTTOU = syscall.Signal(0x16) + SIGURG = syscall.Signal(0x17) + SIGUSR1 = syscall.Signal(0xa) + SIGUSR2 = syscall.Signal(0xc) + SIGVTALRM = syscall.Signal(0x1a) + SIGWINCH = syscall.Signal(0x1c) + SIGXCPU = syscall.Signal(0x18) + SIGXFSZ = syscall.Signal(0x19) +) + +// Error table +var errorList = [...]struct { + num syscall.Errno + name string + desc string +}{ + {1, "EPERM", "operation not permitted"}, + {2, "ENOENT", "no such file or directory"}, + {3, "ESRCH", "no such process"}, + {4, "EINTR", "interrupted system call"}, + {5, "EIO", "input/output error"}, + {6, "ENXIO", "no such device or address"}, + {7, "E2BIG", "argument list too long"}, + {8, "ENOEXEC", "exec format error"}, + {9, "EBADF", "bad file descriptor"}, + {10, "ECHILD", "no child processes"}, + {11, "EAGAIN", "resource temporarily unavailable"}, + {12, "ENOMEM", "cannot allocate memory"}, + {13, "EACCES", "permission denied"}, + {14, "EFAULT", "bad address"}, + {15, "ENOTBLK", "block device required"}, + {16, "EBUSY", "device or resource busy"}, + {17, "EEXIST", "file exists"}, + {18, "EXDEV", "invalid cross-device link"}, + {19, "ENODEV", "no such device"}, + {20, "ENOTDIR", "not a directory"}, + {21, "EISDIR", "is a directory"}, + {22, "EINVAL", "invalid argument"}, + {23, "ENFILE", "too many open files in system"}, + {24, "EMFILE", "too many open files"}, + {25, "ENOTTY", "inappropriate ioctl for device"}, + {26, "ETXTBSY", "text file busy"}, + {27, "EFBIG", "file too large"}, + {28, "ENOSPC", "no space left on device"}, + {29, "ESPIPE", "illegal seek"}, + {30, "EROFS", "read-only file system"}, + {31, "EMLINK", "too many links"}, + {32, "EPIPE", "broken pipe"}, + {33, "EDOM", "numerical argument out of domain"}, + {34, "ERANGE", "numerical result out of range"}, + {35, "EDEADLK", "resource deadlock avoided"}, + {36, "ENAMETOOLONG", "file name too long"}, + {37, "ENOLCK", "no locks available"}, + {38, "ENOSYS", "function not implemented"}, + {39, "ENOTEMPTY", "directory not empty"}, + {40, "ELOOP", "too many levels of symbolic links"}, + {42, "ENOMSG", "no message of desired type"}, + {43, "EIDRM", "identifier removed"}, + {44, "ECHRNG", "channel number out of range"}, + {45, "EL2NSYNC", "level 2 not synchronized"}, + {46, "EL3HLT", "level 3 halted"}, + {47, "EL3RST", "level 3 reset"}, + {48, "ELNRNG", "link number out of range"}, + {49, "EUNATCH", "protocol driver not attached"}, + {50, "ENOCSI", "no CSI structure available"}, + {51, "EL2HLT", "level 2 halted"}, + {52, "EBADE", "invalid exchange"}, + {53, "EBADR", "invalid request descriptor"}, + {54, "EXFULL", "exchange full"}, + {55, "ENOANO", "no anode"}, + {56, "EBADRQC", "invalid request code"}, + {57, "EBADSLT", "invalid slot"}, + {59, "EBFONT", "bad font file format"}, + {60, "ENOSTR", "device not a stream"}, + {61, "ENODATA", "no data available"}, + {62, "ETIME", "timer expired"}, + {63, "ENOSR", "out of streams resources"}, + {64, "ENONET", "machine is not on the network"}, + {65, "ENOPKG", "package not installed"}, + {66, "EREMOTE", "object is remote"}, + {67, "ENOLINK", "link has been severed"}, + {68, "EADV", "advertise error"}, + {69, "ESRMNT", "srmount error"}, + {70, "ECOMM", "communication error on send"}, + {71, "EPROTO", "protocol error"}, + {72, "EMULTIHOP", "multihop attempted"}, + {73, "EDOTDOT", "RFS specific error"}, + {74, "EBADMSG", "bad message"}, + {75, "EOVERFLOW", "value too large for defined data type"}, + {76, "ENOTUNIQ", "name not unique on network"}, + {77, "EBADFD", "file descriptor in bad state"}, + {78, "EREMCHG", "remote address changed"}, + {79, "ELIBACC", "can not access a needed shared library"}, + {80, "ELIBBAD", "accessing a corrupted shared library"}, + {81, "ELIBSCN", ".lib section in a.out corrupted"}, + {82, "ELIBMAX", "attempting to link in too many shared libraries"}, + {83, "ELIBEXEC", "cannot exec a shared library directly"}, + {84, "EILSEQ", "invalid or incomplete multibyte or wide character"}, + {85, "ERESTART", "interrupted system call should be restarted"}, + {86, "ESTRPIPE", "streams pipe error"}, + {87, "EUSERS", "too many users"}, + {88, "ENOTSOCK", "socket operation on non-socket"}, + {89, "EDESTADDRREQ", "destination address required"}, + {90, "EMSGSIZE", "message too long"}, + {91, "EPROTOTYPE", "protocol wrong type for socket"}, + {92, "ENOPROTOOPT", "protocol not available"}, + {93, "EPROTONOSUPPORT", "protocol not supported"}, + {94, "ESOCKTNOSUPPORT", "socket type not supported"}, + {95, "ENOTSUP", "operation not supported"}, + {96, "EPFNOSUPPORT", "protocol family not supported"}, + {97, "EAFNOSUPPORT", "address family not supported by protocol"}, + {98, "EADDRINUSE", "address already in use"}, + {99, "EADDRNOTAVAIL", "cannot assign requested address"}, + {100, "ENETDOWN", "network is down"}, + {101, "ENETUNREACH", "network is unreachable"}, + {102, "ENETRESET", "network dropped connection on reset"}, + {103, "ECONNABORTED", "software caused connection abort"}, + {104, "ECONNRESET", "connection reset by peer"}, + {105, "ENOBUFS", "no buffer space available"}, + {106, "EISCONN", "transport endpoint is already connected"}, + {107, "ENOTCONN", "transport endpoint is not connected"}, + {108, "ESHUTDOWN", "cannot send after transport endpoint shutdown"}, + {109, "ETOOMANYREFS", "too many references: cannot splice"}, + {110, "ETIMEDOUT", "connection timed out"}, + {111, "ECONNREFUSED", "connection refused"}, + {112, "EHOSTDOWN", "host is down"}, + {113, "EHOSTUNREACH", "no route to host"}, + {114, "EALREADY", "operation already in progress"}, + {115, "EINPROGRESS", "operation now in progress"}, + {116, "ESTALE", "stale file handle"}, + {117, "EUCLEAN", "structure needs cleaning"}, + {118, "ENOTNAM", "not a XENIX named type file"}, + {119, "ENAVAIL", "no XENIX semaphores available"}, + {120, "EISNAM", "is a named type file"}, + {121, "EREMOTEIO", "remote I/O error"}, + {122, "EDQUOT", "disk quota exceeded"}, + {123, "ENOMEDIUM", "no medium found"}, + {124, "EMEDIUMTYPE", "wrong medium type"}, + {125, "ECANCELED", "operation canceled"}, + {126, "ENOKEY", "required key not available"}, + {127, "EKEYEXPIRED", "key has expired"}, + {128, "EKEYREVOKED", "key has been revoked"}, + {129, "EKEYREJECTED", "key was rejected by service"}, + {130, "EOWNERDEAD", "owner died"}, + {131, "ENOTRECOVERABLE", "state not recoverable"}, + {132, "ERFKILL", "operation not possible due to RF-kill"}, + {133, "EHWPOISON", "memory page has hardware error"}, +} + +// Signal table +var signalList = [...]struct { + num syscall.Signal + name string + desc string +}{ + {1, "SIGHUP", "hangup"}, + {2, "SIGINT", "interrupt"}, + {3, "SIGQUIT", "quit"}, + {4, "SIGILL", "illegal instruction"}, + {5, "SIGTRAP", "trace/breakpoint trap"}, + {6, "SIGABRT", "aborted"}, + {7, "SIGBUS", "bus error"}, + {8, "SIGFPE", "floating point exception"}, + {9, "SIGKILL", "killed"}, + {10, "SIGUSR1", "user defined signal 1"}, + {11, "SIGSEGV", "segmentation fault"}, + {12, "SIGUSR2", "user defined signal 2"}, + {13, "SIGPIPE", "broken pipe"}, + {14, "SIGALRM", "alarm clock"}, + {15, "SIGTERM", "terminated"}, + {16, "SIGSTKFLT", "stack fault"}, + {17, "SIGCHLD", "child exited"}, + {18, "SIGCONT", "continued"}, + {19, "SIGSTOP", "stopped (signal)"}, + {20, "SIGTSTP", "stopped"}, + {21, "SIGTTIN", "stopped (tty input)"}, + {22, "SIGTTOU", "stopped (tty output)"}, + {23, "SIGURG", "urgent I/O condition"}, + {24, "SIGXCPU", "CPU time limit exceeded"}, + {25, "SIGXFSZ", "file size limit exceeded"}, + {26, "SIGVTALRM", "virtual timer expired"}, + {27, "SIGPROF", "profiling timer expired"}, + {28, "SIGWINCH", "window changed"}, + {29, "SIGIO", "I/O possible"}, + {30, "SIGPWR", "power failure"}, + {31, "SIGSYS", "bad system call"}, +} diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go b/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go index fba68b8..5a057da 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go @@ -1952,6 +1952,9 @@ const ( STATX_TYPE = 0x1 STATX_UID = 0x8 STATX__RESERVED = 0x80000000 + SYNC_FILE_RANGE_WAIT_AFTER = 0x4 + SYNC_FILE_RANGE_WAIT_BEFORE = 0x1 + SYNC_FILE_RANGE_WRITE = 0x2 SYSFS_MAGIC = 0x62656572 S_BLKSIZE = 0x200 S_IEXEC = 0x40 diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64.go b/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64.go index 2f7110d..f3fae1d 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64.go @@ -1998,16 +1998,6 @@ func Statfs(path string, buf *Statfs_t) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func SyncFileRange(fd int, off int64, n int64, flags int) (err error) { - _, _, e1 := Syscall6(SYS_SYNC_FILE_RANGE2, uintptr(fd), uintptr(off), uintptr(n), uintptr(flags), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func Truncate(path string, length int64) (err error) { var _p0 *byte _p0, err = BytePtrFromString(path) @@ -2317,3 +2307,13 @@ func poll(fds *PollFd, nfds int, timeout int) (n int, err error) { } return } + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func syncFileRange2(fd int, flags int, off int64, n int64) (err error) { + _, _, e1 := Syscall6(SYS_SYNC_FILE_RANGE2, uintptr(fd), uintptr(flags), uintptr(off), uintptr(n), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64le.go b/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64le.go index bb3bd59..011b0a5 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64le.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64le.go @@ -1998,16 +1998,6 @@ func Statfs(path string, buf *Statfs_t) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func SyncFileRange(fd int, off int64, n int64, flags int) (err error) { - _, _, e1 := Syscall6(SYS_SYNC_FILE_RANGE2, uintptr(fd), uintptr(off), uintptr(n), uintptr(flags), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func Truncate(path string, length int64) (err error) { var _p0 *byte _p0, err = BytePtrFromString(path) @@ -2317,3 +2307,13 @@ func poll(fds *PollFd, nfds int, timeout int) (n int, err error) { } return } + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func syncFileRange2(fd int, flags int, off int64, n int64) (err error) { + _, _, e1 := Syscall6(SYS_SYNC_FILE_RANGE2, uintptr(fd), uintptr(flags), uintptr(off), uintptr(n), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux_riscv64.go b/vendor/golang.org/x/sys/unix/zsyscall_linux_riscv64.go new file mode 100644 index 0000000..b086f7e --- /dev/null +++ b/vendor/golang.org/x/sys/unix/zsyscall_linux_riscv64.go @@ -0,0 +1,2114 @@ +// mksyscall.pl -tags linux,riscv64 syscall_linux.go syscall_linux_riscv64.go +// Code generated by the command above; see README.md. DO NOT EDIT. + +// +build linux,riscv64 + +package unix + +import ( + "syscall" + "unsafe" +) + +var _ syscall.Errno + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func fchmodat(dirfd int, path string, mode uint32) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_FCHMODAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func ioctl(fd int, req uint, arg uintptr) (err error) { + _, _, e1 := Syscall(SYS_IOCTL, uintptr(fd), uintptr(req), uintptr(arg)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Linkat(olddirfd int, oldpath string, newdirfd int, newpath string, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(oldpath) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(newpath) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_LINKAT, uintptr(olddirfd), uintptr(unsafe.Pointer(_p0)), uintptr(newdirfd), uintptr(unsafe.Pointer(_p1)), uintptr(flags), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func openat(dirfd int, path string, flags int, mode uint32) (fd int, err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + r0, _, e1 := Syscall6(SYS_OPENAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(flags), uintptr(mode), 0, 0) + fd = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func ppoll(fds *PollFd, nfds int, timeout *Timespec, sigmask *Sigset_t) (n int, err error) { + r0, _, e1 := Syscall6(SYS_PPOLL, uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(unsafe.Pointer(timeout)), uintptr(unsafe.Pointer(sigmask)), 0, 0) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Readlinkat(dirfd int, path string, buf []byte) (n int, err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + var _p1 unsafe.Pointer + if len(buf) > 0 { + _p1 = unsafe.Pointer(&buf[0]) + } else { + _p1 = unsafe.Pointer(&_zero) + } + r0, _, e1 := Syscall6(SYS_READLINKAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)), 0, 0) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Symlinkat(oldpath string, newdirfd int, newpath string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(oldpath) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(newpath) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_SYMLINKAT, uintptr(unsafe.Pointer(_p0)), uintptr(newdirfd), uintptr(unsafe.Pointer(_p1))) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Unlinkat(dirfd int, path string, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_UNLINKAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(flags)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_UTIMENSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Getcwd(buf []byte) (n int, err error) { + var _p0 unsafe.Pointer + if len(buf) > 0 { + _p0 = unsafe.Pointer(&buf[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + r0, _, e1 := Syscall(SYS_GETCWD, uintptr(_p0), uintptr(len(buf)), 0) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func wait4(pid int, wstatus *_C_int, options int, rusage *Rusage) (wpid int, err error) { + r0, _, e1 := Syscall6(SYS_WAIT4, uintptr(pid), uintptr(unsafe.Pointer(wstatus)), uintptr(options), uintptr(unsafe.Pointer(rusage)), 0, 0) + wpid = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func KeyctlInt(cmd int, arg2 int, arg3 int, arg4 int, arg5 int) (ret int, err error) { + r0, _, e1 := Syscall6(SYS_KEYCTL, uintptr(cmd), uintptr(arg2), uintptr(arg3), uintptr(arg4), uintptr(arg5), 0) + ret = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func KeyctlBuffer(cmd int, arg2 int, buf []byte, arg5 int) (ret int, err error) { + var _p0 unsafe.Pointer + if len(buf) > 0 { + _p0 = unsafe.Pointer(&buf[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + r0, _, e1 := Syscall6(SYS_KEYCTL, uintptr(cmd), uintptr(arg2), uintptr(_p0), uintptr(len(buf)), uintptr(arg5), 0) + ret = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func keyctlJoin(cmd int, arg2 string) (ret int, err error) { + var _p0 *byte + _p0, err = BytePtrFromString(arg2) + if err != nil { + return + } + r0, _, e1 := Syscall(SYS_KEYCTL, uintptr(cmd), uintptr(unsafe.Pointer(_p0)), 0) + ret = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func keyctlSearch(cmd int, arg2 int, arg3 string, arg4 string, arg5 int) (ret int, err error) { + var _p0 *byte + _p0, err = BytePtrFromString(arg3) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(arg4) + if err != nil { + return + } + r0, _, e1 := Syscall6(SYS_KEYCTL, uintptr(cmd), uintptr(arg2), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(arg5), 0) + ret = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func keyctlIOV(cmd int, arg2 int, payload []Iovec, arg5 int) (err error) { + var _p0 unsafe.Pointer + if len(payload) > 0 { + _p0 = unsafe.Pointer(&payload[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall6(SYS_KEYCTL, uintptr(cmd), uintptr(arg2), uintptr(_p0), uintptr(len(payload)), uintptr(arg5), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func keyctlDH(cmd int, arg2 *KeyctlDHParams, buf []byte) (ret int, err error) { + var _p0 unsafe.Pointer + if len(buf) > 0 { + _p0 = unsafe.Pointer(&buf[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + r0, _, e1 := Syscall6(SYS_KEYCTL, uintptr(cmd), uintptr(unsafe.Pointer(arg2)), uintptr(_p0), uintptr(len(buf)), 0, 0) + ret = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func ptrace(request int, pid int, addr uintptr, data uintptr) (err error) { + _, _, e1 := Syscall6(SYS_PTRACE, uintptr(request), uintptr(pid), uintptr(addr), uintptr(data), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func reboot(magic1 uint, magic2 uint, cmd int, arg string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(arg) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_REBOOT, uintptr(magic1), uintptr(magic2), uintptr(cmd), uintptr(unsafe.Pointer(_p0)), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func mount(source string, target string, fstype string, flags uintptr, data *byte) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(source) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(target) + if err != nil { + return + } + var _p2 *byte + _p2, err = BytePtrFromString(fstype) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_MOUNT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(unsafe.Pointer(_p2)), uintptr(flags), uintptr(unsafe.Pointer(data)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Acct(path string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_ACCT, uintptr(unsafe.Pointer(_p0)), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func AddKey(keyType string, description string, payload []byte, ringid int) (id int, err error) { + var _p0 *byte + _p0, err = BytePtrFromString(keyType) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(description) + if err != nil { + return + } + var _p2 unsafe.Pointer + if len(payload) > 0 { + _p2 = unsafe.Pointer(&payload[0]) + } else { + _p2 = unsafe.Pointer(&_zero) + } + r0, _, e1 := Syscall6(SYS_ADD_KEY, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(_p2), uintptr(len(payload)), uintptr(ringid), 0) + id = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Adjtimex(buf *Timex) (state int, err error) { + r0, _, e1 := Syscall(SYS_ADJTIMEX, uintptr(unsafe.Pointer(buf)), 0, 0) + state = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Chdir(path string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_CHDIR, uintptr(unsafe.Pointer(_p0)), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Chroot(path string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_CHROOT, uintptr(unsafe.Pointer(_p0)), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func ClockGettime(clockid int32, time *Timespec) (err error) { + _, _, e1 := Syscall(SYS_CLOCK_GETTIME, uintptr(clockid), uintptr(unsafe.Pointer(time)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Close(fd int) (err error) { + _, _, e1 := Syscall(SYS_CLOSE, uintptr(fd), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func CopyFileRange(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int, err error) { + r0, _, e1 := Syscall6(SYS_COPY_FILE_RANGE, uintptr(rfd), uintptr(unsafe.Pointer(roff)), uintptr(wfd), uintptr(unsafe.Pointer(woff)), uintptr(len), uintptr(flags)) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Dup(oldfd int) (fd int, err error) { + r0, _, e1 := Syscall(SYS_DUP, uintptr(oldfd), 0, 0) + fd = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Dup3(oldfd int, newfd int, flags int) (err error) { + _, _, e1 := Syscall(SYS_DUP3, uintptr(oldfd), uintptr(newfd), uintptr(flags)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func EpollCreate1(flag int) (fd int, err error) { + r0, _, e1 := RawSyscall(SYS_EPOLL_CREATE1, uintptr(flag), 0, 0) + fd = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func EpollCtl(epfd int, op int, fd int, event *EpollEvent) (err error) { + _, _, e1 := RawSyscall6(SYS_EPOLL_CTL, uintptr(epfd), uintptr(op), uintptr(fd), uintptr(unsafe.Pointer(event)), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Eventfd(initval uint, flags int) (fd int, err error) { + r0, _, e1 := Syscall(SYS_EVENTFD2, uintptr(initval), uintptr(flags), 0) + fd = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Exit(code int) { + SyscallNoError(SYS_EXIT_GROUP, uintptr(code), 0, 0) + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Fallocate(fd int, mode uint32, off int64, len int64) (err error) { + _, _, e1 := Syscall6(SYS_FALLOCATE, uintptr(fd), uintptr(mode), uintptr(off), uintptr(len), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Fchdir(fd int) (err error) { + _, _, e1 := Syscall(SYS_FCHDIR, uintptr(fd), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Fchmod(fd int, mode uint32) (err error) { + _, _, e1 := Syscall(SYS_FCHMOD, uintptr(fd), uintptr(mode), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_FCHOWNAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid), uintptr(flags), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func fcntl(fd int, cmd int, arg int) (val int, err error) { + r0, _, e1 := Syscall(SYS_FCNTL, uintptr(fd), uintptr(cmd), uintptr(arg)) + val = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Fdatasync(fd int) (err error) { + _, _, e1 := Syscall(SYS_FDATASYNC, uintptr(fd), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Fgetxattr(fd int, attr string, dest []byte) (sz int, err error) { + var _p0 *byte + _p0, err = BytePtrFromString(attr) + if err != nil { + return + } + var _p1 unsafe.Pointer + if len(dest) > 0 { + _p1 = unsafe.Pointer(&dest[0]) + } else { + _p1 = unsafe.Pointer(&_zero) + } + r0, _, e1 := Syscall6(SYS_FGETXATTR, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(dest)), 0, 0) + sz = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Flistxattr(fd int, dest []byte) (sz int, err error) { + var _p0 unsafe.Pointer + if len(dest) > 0 { + _p0 = unsafe.Pointer(&dest[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + r0, _, e1 := Syscall(SYS_FLISTXATTR, uintptr(fd), uintptr(_p0), uintptr(len(dest))) + sz = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Flock(fd int, how int) (err error) { + _, _, e1 := Syscall(SYS_FLOCK, uintptr(fd), uintptr(how), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Fremovexattr(fd int, attr string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(attr) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_FREMOVEXATTR, uintptr(fd), uintptr(unsafe.Pointer(_p0)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Fsetxattr(fd int, attr string, dest []byte, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(attr) + if err != nil { + return + } + var _p1 unsafe.Pointer + if len(dest) > 0 { + _p1 = unsafe.Pointer(&dest[0]) + } else { + _p1 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall6(SYS_FSETXATTR, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(dest)), uintptr(flags), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Fsync(fd int) (err error) { + _, _, e1 := Syscall(SYS_FSYNC, uintptr(fd), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Getdents(fd int, buf []byte) (n int, err error) { + var _p0 unsafe.Pointer + if len(buf) > 0 { + _p0 = unsafe.Pointer(&buf[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + r0, _, e1 := Syscall(SYS_GETDENTS64, uintptr(fd), uintptr(_p0), uintptr(len(buf))) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Getpgid(pid int) (pgid int, err error) { + r0, _, e1 := RawSyscall(SYS_GETPGID, uintptr(pid), 0, 0) + pgid = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Getpid() (pid int) { + r0, _ := RawSyscallNoError(SYS_GETPID, 0, 0, 0) + pid = int(r0) + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Getppid() (ppid int) { + r0, _ := RawSyscallNoError(SYS_GETPPID, 0, 0, 0) + ppid = int(r0) + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Getpriority(which int, who int) (prio int, err error) { + r0, _, e1 := Syscall(SYS_GETPRIORITY, uintptr(which), uintptr(who), 0) + prio = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Getrandom(buf []byte, flags int) (n int, err error) { + var _p0 unsafe.Pointer + if len(buf) > 0 { + _p0 = unsafe.Pointer(&buf[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + r0, _, e1 := Syscall(SYS_GETRANDOM, uintptr(_p0), uintptr(len(buf)), uintptr(flags)) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Getrusage(who int, rusage *Rusage) (err error) { + _, _, e1 := RawSyscall(SYS_GETRUSAGE, uintptr(who), uintptr(unsafe.Pointer(rusage)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Getsid(pid int) (sid int, err error) { + r0, _, e1 := RawSyscall(SYS_GETSID, uintptr(pid), 0, 0) + sid = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Gettid() (tid int) { + r0, _ := RawSyscallNoError(SYS_GETTID, 0, 0, 0) + tid = int(r0) + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Getxattr(path string, attr string, dest []byte) (sz int, err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(attr) + if err != nil { + return + } + var _p2 unsafe.Pointer + if len(dest) > 0 { + _p2 = unsafe.Pointer(&dest[0]) + } else { + _p2 = unsafe.Pointer(&_zero) + } + r0, _, e1 := Syscall6(SYS_GETXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(_p2), uintptr(len(dest)), 0, 0) + sz = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func InotifyAddWatch(fd int, pathname string, mask uint32) (watchdesc int, err error) { + var _p0 *byte + _p0, err = BytePtrFromString(pathname) + if err != nil { + return + } + r0, _, e1 := Syscall(SYS_INOTIFY_ADD_WATCH, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(mask)) + watchdesc = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func InotifyInit1(flags int) (fd int, err error) { + r0, _, e1 := RawSyscall(SYS_INOTIFY_INIT1, uintptr(flags), 0, 0) + fd = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func InotifyRmWatch(fd int, watchdesc uint32) (success int, err error) { + r0, _, e1 := RawSyscall(SYS_INOTIFY_RM_WATCH, uintptr(fd), uintptr(watchdesc), 0) + success = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Kill(pid int, sig syscall.Signal) (err error) { + _, _, e1 := RawSyscall(SYS_KILL, uintptr(pid), uintptr(sig), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Klogctl(typ int, buf []byte) (n int, err error) { + var _p0 unsafe.Pointer + if len(buf) > 0 { + _p0 = unsafe.Pointer(&buf[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + r0, _, e1 := Syscall(SYS_SYSLOG, uintptr(typ), uintptr(_p0), uintptr(len(buf))) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Lgetxattr(path string, attr string, dest []byte) (sz int, err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(attr) + if err != nil { + return + } + var _p2 unsafe.Pointer + if len(dest) > 0 { + _p2 = unsafe.Pointer(&dest[0]) + } else { + _p2 = unsafe.Pointer(&_zero) + } + r0, _, e1 := Syscall6(SYS_LGETXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(_p2), uintptr(len(dest)), 0, 0) + sz = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Listxattr(path string, dest []byte) (sz int, err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + var _p1 unsafe.Pointer + if len(dest) > 0 { + _p1 = unsafe.Pointer(&dest[0]) + } else { + _p1 = unsafe.Pointer(&_zero) + } + r0, _, e1 := Syscall(SYS_LISTXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(dest))) + sz = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Llistxattr(path string, dest []byte) (sz int, err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + var _p1 unsafe.Pointer + if len(dest) > 0 { + _p1 = unsafe.Pointer(&dest[0]) + } else { + _p1 = unsafe.Pointer(&_zero) + } + r0, _, e1 := Syscall(SYS_LLISTXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(dest))) + sz = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Lremovexattr(path string, attr string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(attr) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_LREMOVEXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Lsetxattr(path string, attr string, data []byte, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(attr) + if err != nil { + return + } + var _p2 unsafe.Pointer + if len(data) > 0 { + _p2 = unsafe.Pointer(&data[0]) + } else { + _p2 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall6(SYS_LSETXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(_p2), uintptr(len(data)), uintptr(flags), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Mkdirat(dirfd int, path string, mode uint32) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_MKDIRAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Mknodat(dirfd int, path string, mode uint32, dev int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_MKNODAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Nanosleep(time *Timespec, leftover *Timespec) (err error) { + _, _, e1 := Syscall(SYS_NANOSLEEP, uintptr(unsafe.Pointer(time)), uintptr(unsafe.Pointer(leftover)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func PerfEventOpen(attr *PerfEventAttr, pid int, cpu int, groupFd int, flags int) (fd int, err error) { + r0, _, e1 := Syscall6(SYS_PERF_EVENT_OPEN, uintptr(unsafe.Pointer(attr)), uintptr(pid), uintptr(cpu), uintptr(groupFd), uintptr(flags), 0) + fd = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func PivotRoot(newroot string, putold string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(newroot) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(putold) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_PIVOT_ROOT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func prlimit(pid int, resource int, newlimit *Rlimit, old *Rlimit) (err error) { + _, _, e1 := RawSyscall6(SYS_PRLIMIT64, uintptr(pid), uintptr(resource), uintptr(unsafe.Pointer(newlimit)), uintptr(unsafe.Pointer(old)), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Prctl(option int, arg2 uintptr, arg3 uintptr, arg4 uintptr, arg5 uintptr) (err error) { + _, _, e1 := Syscall6(SYS_PRCTL, uintptr(option), uintptr(arg2), uintptr(arg3), uintptr(arg4), uintptr(arg5), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Pselect(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timespec, sigmask *Sigset_t) (n int, err error) { + r0, _, e1 := Syscall6(SYS_PSELECT6, uintptr(nfd), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), uintptr(unsafe.Pointer(sigmask))) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func read(fd int, p []byte) (n int, err error) { + var _p0 unsafe.Pointer + if len(p) > 0 { + _p0 = unsafe.Pointer(&p[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(_p0), uintptr(len(p))) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Removexattr(path string, attr string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(attr) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_REMOVEXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(oldpath) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(newpath) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_RENAMEAT, uintptr(olddirfd), uintptr(unsafe.Pointer(_p0)), uintptr(newdirfd), uintptr(unsafe.Pointer(_p1)), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Renameat2(olddirfd int, oldpath string, newdirfd int, newpath string, flags uint) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(oldpath) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(newpath) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_RENAMEAT2, uintptr(olddirfd), uintptr(unsafe.Pointer(_p0)), uintptr(newdirfd), uintptr(unsafe.Pointer(_p1)), uintptr(flags), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func RequestKey(keyType string, description string, callback string, destRingid int) (id int, err error) { + var _p0 *byte + _p0, err = BytePtrFromString(keyType) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(description) + if err != nil { + return + } + var _p2 *byte + _p2, err = BytePtrFromString(callback) + if err != nil { + return + } + r0, _, e1 := Syscall6(SYS_REQUEST_KEY, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(unsafe.Pointer(_p2)), uintptr(destRingid), 0, 0) + id = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Setdomainname(p []byte) (err error) { + var _p0 unsafe.Pointer + if len(p) > 0 { + _p0 = unsafe.Pointer(&p[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall(SYS_SETDOMAINNAME, uintptr(_p0), uintptr(len(p)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Sethostname(p []byte) (err error) { + var _p0 unsafe.Pointer + if len(p) > 0 { + _p0 = unsafe.Pointer(&p[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall(SYS_SETHOSTNAME, uintptr(_p0), uintptr(len(p)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Setpgid(pid int, pgid int) (err error) { + _, _, e1 := RawSyscall(SYS_SETPGID, uintptr(pid), uintptr(pgid), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Setsid() (pid int, err error) { + r0, _, e1 := RawSyscall(SYS_SETSID, 0, 0, 0) + pid = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Settimeofday(tv *Timeval) (err error) { + _, _, e1 := RawSyscall(SYS_SETTIMEOFDAY, uintptr(unsafe.Pointer(tv)), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Setns(fd int, nstype int) (err error) { + _, _, e1 := Syscall(SYS_SETNS, uintptr(fd), uintptr(nstype), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Setpriority(which int, who int, prio int) (err error) { + _, _, e1 := Syscall(SYS_SETPRIORITY, uintptr(which), uintptr(who), uintptr(prio)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Setxattr(path string, attr string, data []byte, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(attr) + if err != nil { + return + } + var _p2 unsafe.Pointer + if len(data) > 0 { + _p2 = unsafe.Pointer(&data[0]) + } else { + _p2 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall6(SYS_SETXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(_p2), uintptr(len(data)), uintptr(flags), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Statx(dirfd int, path string, flags int, mask int, stat *Statx_t) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_STATX, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(flags), uintptr(mask), uintptr(unsafe.Pointer(stat)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Sync() { + SyscallNoError(SYS_SYNC, 0, 0, 0) + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Syncfs(fd int) (err error) { + _, _, e1 := Syscall(SYS_SYNCFS, uintptr(fd), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Sysinfo(info *Sysinfo_t) (err error) { + _, _, e1 := RawSyscall(SYS_SYSINFO, uintptr(unsafe.Pointer(info)), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Tee(rfd int, wfd int, len int, flags int) (n int64, err error) { + r0, _, e1 := Syscall6(SYS_TEE, uintptr(rfd), uintptr(wfd), uintptr(len), uintptr(flags), 0, 0) + n = int64(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Tgkill(tgid int, tid int, sig syscall.Signal) (err error) { + _, _, e1 := RawSyscall(SYS_TGKILL, uintptr(tgid), uintptr(tid), uintptr(sig)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Times(tms *Tms) (ticks uintptr, err error) { + r0, _, e1 := RawSyscall(SYS_TIMES, uintptr(unsafe.Pointer(tms)), 0, 0) + ticks = uintptr(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Umask(mask int) (oldmask int) { + r0, _ := RawSyscallNoError(SYS_UMASK, uintptr(mask), 0, 0) + oldmask = int(r0) + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Uname(buf *Utsname) (err error) { + _, _, e1 := RawSyscall(SYS_UNAME, uintptr(unsafe.Pointer(buf)), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Unmount(target string, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(target) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_UMOUNT2, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Unshare(flags int) (err error) { + _, _, e1 := Syscall(SYS_UNSHARE, uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func write(fd int, p []byte) (n int, err error) { + var _p0 unsafe.Pointer + if len(p) > 0 { + _p0 = unsafe.Pointer(&p[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(_p0), uintptr(len(p))) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func exitThread(code int) (err error) { + _, _, e1 := Syscall(SYS_EXIT, uintptr(code), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func readlen(fd int, p *byte, np int) (n int, err error) { + r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(unsafe.Pointer(p)), uintptr(np)) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func writelen(fd int, p *byte, np int) (n int, err error) { + r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(unsafe.Pointer(p)), uintptr(np)) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func munmap(addr uintptr, length uintptr) (err error) { + _, _, e1 := Syscall(SYS_MUNMAP, uintptr(addr), uintptr(length), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Madvise(b []byte, advice int) (err error) { + var _p0 unsafe.Pointer + if len(b) > 0 { + _p0 = unsafe.Pointer(&b[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall(SYS_MADVISE, uintptr(_p0), uintptr(len(b)), uintptr(advice)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Mprotect(b []byte, prot int) (err error) { + var _p0 unsafe.Pointer + if len(b) > 0 { + _p0 = unsafe.Pointer(&b[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall(SYS_MPROTECT, uintptr(_p0), uintptr(len(b)), uintptr(prot)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Mlock(b []byte) (err error) { + var _p0 unsafe.Pointer + if len(b) > 0 { + _p0 = unsafe.Pointer(&b[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall(SYS_MLOCK, uintptr(_p0), uintptr(len(b)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Mlockall(flags int) (err error) { + _, _, e1 := Syscall(SYS_MLOCKALL, uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Msync(b []byte, flags int) (err error) { + var _p0 unsafe.Pointer + if len(b) > 0 { + _p0 = unsafe.Pointer(&b[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall(SYS_MSYNC, uintptr(_p0), uintptr(len(b)), uintptr(flags)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Munlock(b []byte) (err error) { + var _p0 unsafe.Pointer + if len(b) > 0 { + _p0 = unsafe.Pointer(&b[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall(SYS_MUNLOCK, uintptr(_p0), uintptr(len(b)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Munlockall() (err error) { + _, _, e1 := Syscall(SYS_MUNLOCKALL, 0, 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func faccessat(dirfd int, path string, mode uint32) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_FACCESSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) { + var _p0 unsafe.Pointer + if len(events) > 0 { + _p0 = unsafe.Pointer(&events[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + r0, _, e1 := Syscall6(SYS_EPOLL_PWAIT, uintptr(epfd), uintptr(_p0), uintptr(len(events)), uintptr(msec), 0, 0) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Fadvise(fd int, offset int64, length int64, advice int) (err error) { + _, _, e1 := Syscall6(SYS_FADVISE64, uintptr(fd), uintptr(offset), uintptr(length), uintptr(advice), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Fchown(fd int, uid int, gid int) (err error) { + _, _, e1 := Syscall(SYS_FCHOWN, uintptr(fd), uintptr(uid), uintptr(gid)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Fstat(fd int, stat *Stat_t) (err error) { + _, _, e1 := Syscall(SYS_FSTAT, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_FSTATAT, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Fstatfs(fd int, buf *Statfs_t) (err error) { + _, _, e1 := Syscall(SYS_FSTATFS, uintptr(fd), uintptr(unsafe.Pointer(buf)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Ftruncate(fd int, length int64) (err error) { + _, _, e1 := Syscall(SYS_FTRUNCATE, uintptr(fd), uintptr(length), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Getegid() (egid int) { + r0, _ := RawSyscallNoError(SYS_GETEGID, 0, 0, 0) + egid = int(r0) + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Geteuid() (euid int) { + r0, _ := RawSyscallNoError(SYS_GETEUID, 0, 0, 0) + euid = int(r0) + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Getgid() (gid int) { + r0, _ := RawSyscallNoError(SYS_GETGID, 0, 0, 0) + gid = int(r0) + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Getrlimit(resource int, rlim *Rlimit) (err error) { + _, _, e1 := RawSyscall(SYS_GETRLIMIT, uintptr(resource), uintptr(unsafe.Pointer(rlim)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Getuid() (uid int) { + r0, _ := RawSyscallNoError(SYS_GETUID, 0, 0, 0) + uid = int(r0) + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Listen(s int, n int) (err error) { + _, _, e1 := Syscall(SYS_LISTEN, uintptr(s), uintptr(n), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Pread(fd int, p []byte, offset int64) (n int, err error) { + var _p0 unsafe.Pointer + if len(p) > 0 { + _p0 = unsafe.Pointer(&p[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + r0, _, e1 := Syscall6(SYS_PREAD64, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), 0, 0) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Pwrite(fd int, p []byte, offset int64) (n int, err error) { + var _p0 unsafe.Pointer + if len(p) > 0 { + _p0 = unsafe.Pointer(&p[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + r0, _, e1 := Syscall6(SYS_PWRITE64, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), 0, 0) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Seek(fd int, offset int64, whence int) (off int64, err error) { + r0, _, e1 := Syscall(SYS_LSEEK, uintptr(fd), uintptr(offset), uintptr(whence)) + off = int64(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) { + r0, _, e1 := Syscall6(SYS_SENDFILE, uintptr(outfd), uintptr(infd), uintptr(unsafe.Pointer(offset)), uintptr(count), 0, 0) + written = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Setfsgid(gid int) (err error) { + _, _, e1 := Syscall(SYS_SETFSGID, uintptr(gid), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Setfsuid(uid int) (err error) { + _, _, e1 := Syscall(SYS_SETFSUID, uintptr(uid), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Setregid(rgid int, egid int) (err error) { + _, _, e1 := RawSyscall(SYS_SETREGID, uintptr(rgid), uintptr(egid), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Setresgid(rgid int, egid int, sgid int) (err error) { + _, _, e1 := RawSyscall(SYS_SETRESGID, uintptr(rgid), uintptr(egid), uintptr(sgid)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Setresuid(ruid int, euid int, suid int) (err error) { + _, _, e1 := RawSyscall(SYS_SETRESUID, uintptr(ruid), uintptr(euid), uintptr(suid)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Setrlimit(resource int, rlim *Rlimit) (err error) { + _, _, e1 := RawSyscall(SYS_SETRLIMIT, uintptr(resource), uintptr(unsafe.Pointer(rlim)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Setreuid(ruid int, euid int) (err error) { + _, _, e1 := RawSyscall(SYS_SETREUID, uintptr(ruid), uintptr(euid), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Shutdown(fd int, how int) (err error) { + _, _, e1 := Syscall(SYS_SHUTDOWN, uintptr(fd), uintptr(how), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error) { + r0, _, e1 := Syscall6(SYS_SPLICE, uintptr(rfd), uintptr(unsafe.Pointer(roff)), uintptr(wfd), uintptr(unsafe.Pointer(woff)), uintptr(len), uintptr(flags)) + n = int64(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Statfs(path string, buf *Statfs_t) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_STATFS, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(buf)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func SyncFileRange(fd int, off int64, n int64, flags int) (err error) { + _, _, e1 := Syscall6(SYS_SYNC_FILE_RANGE, uintptr(fd), uintptr(off), uintptr(n), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Truncate(path string, length int64) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_TRUNCATE, uintptr(unsafe.Pointer(_p0)), uintptr(length), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) { + r0, _, e1 := Syscall(SYS_ACCEPT, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen))) + fd = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error) { + r0, _, e1 := Syscall6(SYS_ACCEPT4, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), uintptr(flags), 0, 0) + fd = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) { + _, _, e1 := Syscall(SYS_BIND, uintptr(s), uintptr(addr), uintptr(addrlen)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) { + _, _, e1 := Syscall(SYS_CONNECT, uintptr(s), uintptr(addr), uintptr(addrlen)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func getgroups(n int, list *_Gid_t) (nn int, err error) { + r0, _, e1 := RawSyscall(SYS_GETGROUPS, uintptr(n), uintptr(unsafe.Pointer(list)), 0) + nn = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func setgroups(n int, list *_Gid_t) (err error) { + _, _, e1 := RawSyscall(SYS_SETGROUPS, uintptr(n), uintptr(unsafe.Pointer(list)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error) { + _, _, e1 := Syscall6(SYS_GETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(unsafe.Pointer(vallen)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error) { + _, _, e1 := Syscall6(SYS_SETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(vallen), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func socket(domain int, typ int, proto int) (fd int, err error) { + r0, _, e1 := RawSyscall(SYS_SOCKET, uintptr(domain), uintptr(typ), uintptr(proto)) + fd = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func socketpair(domain int, typ int, proto int, fd *[2]int32) (err error) { + _, _, e1 := RawSyscall6(SYS_SOCKETPAIR, uintptr(domain), uintptr(typ), uintptr(proto), uintptr(unsafe.Pointer(fd)), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) { + _, _, e1 := RawSyscall(SYS_GETPEERNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen))) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) { + _, _, e1 := RawSyscall(SYS_GETSOCKNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen))) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) { + var _p0 unsafe.Pointer + if len(p) > 0 { + _p0 = unsafe.Pointer(&p[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + r0, _, e1 := Syscall6(SYS_RECVFROM, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen))) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) { + var _p0 unsafe.Pointer + if len(buf) > 0 { + _p0 = unsafe.Pointer(&buf[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall6(SYS_SENDTO, uintptr(s), uintptr(_p0), uintptr(len(buf)), uintptr(flags), uintptr(to), uintptr(addrlen)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func recvmsg(s int, msg *Msghdr, flags int) (n int, err error) { + r0, _, e1 := Syscall(SYS_RECVMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags)) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func sendmsg(s int, msg *Msghdr, flags int) (n int, err error) { + r0, _, e1 := Syscall(SYS_SENDMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags)) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func mmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset int64) (xaddr uintptr, err error) { + r0, _, e1 := Syscall6(SYS_MMAP, uintptr(addr), uintptr(length), uintptr(prot), uintptr(flags), uintptr(fd), uintptr(offset)) + xaddr = uintptr(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Gettimeofday(tv *Timeval) (err error) { + _, _, e1 := RawSyscall(SYS_GETTIMEOFDAY, uintptr(unsafe.Pointer(tv)), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func pipe2(p *[2]_C_int, flags int) (err error) { + _, _, e1 := RawSyscall(SYS_PIPE2, uintptr(unsafe.Pointer(p)), uintptr(flags), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_riscv64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_riscv64.go new file mode 100644 index 0000000..41e4fd1 --- /dev/null +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_riscv64.go @@ -0,0 +1,286 @@ +// linux/mksysnum.pl -Wall -Werror -static -I/tmp/include /tmp/include/asm/unistd.h +// Code generated by the command above; see README.md. DO NOT EDIT. + +// +build riscv64,linux + +package unix + +const ( + SYS_IO_SETUP = 0 + SYS_IO_DESTROY = 1 + SYS_IO_SUBMIT = 2 + SYS_IO_CANCEL = 3 + SYS_IO_GETEVENTS = 4 + SYS_SETXATTR = 5 + SYS_LSETXATTR = 6 + SYS_FSETXATTR = 7 + SYS_GETXATTR = 8 + SYS_LGETXATTR = 9 + SYS_FGETXATTR = 10 + SYS_LISTXATTR = 11 + SYS_LLISTXATTR = 12 + SYS_FLISTXATTR = 13 + SYS_REMOVEXATTR = 14 + SYS_LREMOVEXATTR = 15 + SYS_FREMOVEXATTR = 16 + SYS_GETCWD = 17 + SYS_LOOKUP_DCOOKIE = 18 + SYS_EVENTFD2 = 19 + SYS_EPOLL_CREATE1 = 20 + SYS_EPOLL_CTL = 21 + SYS_EPOLL_PWAIT = 22 + SYS_DUP = 23 + SYS_DUP3 = 24 + SYS_FCNTL = 25 + SYS_INOTIFY_INIT1 = 26 + SYS_INOTIFY_ADD_WATCH = 27 + SYS_INOTIFY_RM_WATCH = 28 + SYS_IOCTL = 29 + SYS_IOPRIO_SET = 30 + SYS_IOPRIO_GET = 31 + SYS_FLOCK = 32 + SYS_MKNODAT = 33 + SYS_MKDIRAT = 34 + SYS_UNLINKAT = 35 + SYS_SYMLINKAT = 36 + SYS_LINKAT = 37 + SYS_UMOUNT2 = 39 + SYS_MOUNT = 40 + SYS_PIVOT_ROOT = 41 + SYS_NFSSERVCTL = 42 + SYS_STATFS = 43 + SYS_FSTATFS = 44 + SYS_TRUNCATE = 45 + SYS_FTRUNCATE = 46 + SYS_FALLOCATE = 47 + SYS_FACCESSAT = 48 + SYS_CHDIR = 49 + SYS_FCHDIR = 50 + SYS_CHROOT = 51 + SYS_FCHMOD = 52 + SYS_FCHMODAT = 53 + SYS_FCHOWNAT = 54 + SYS_FCHOWN = 55 + SYS_OPENAT = 56 + SYS_CLOSE = 57 + SYS_VHANGUP = 58 + SYS_PIPE2 = 59 + SYS_QUOTACTL = 60 + SYS_GETDENTS64 = 61 + SYS_LSEEK = 62 + SYS_READ = 63 + SYS_WRITE = 64 + SYS_READV = 65 + SYS_WRITEV = 66 + SYS_PREAD64 = 67 + SYS_PWRITE64 = 68 + SYS_PREADV = 69 + SYS_PWRITEV = 70 + SYS_SENDFILE = 71 + SYS_PSELECT6 = 72 + SYS_PPOLL = 73 + SYS_SIGNALFD4 = 74 + SYS_VMSPLICE = 75 + SYS_SPLICE = 76 + SYS_TEE = 77 + SYS_READLINKAT = 78 + SYS_FSTATAT = 79 + SYS_FSTAT = 80 + SYS_SYNC = 81 + SYS_FSYNC = 82 + SYS_FDATASYNC = 83 + SYS_SYNC_FILE_RANGE = 84 + SYS_TIMERFD_CREATE = 85 + SYS_TIMERFD_SETTIME = 86 + SYS_TIMERFD_GETTIME = 87 + SYS_UTIMENSAT = 88 + SYS_ACCT = 89 + SYS_CAPGET = 90 + SYS_CAPSET = 91 + SYS_PERSONALITY = 92 + SYS_EXIT = 93 + SYS_EXIT_GROUP = 94 + SYS_WAITID = 95 + SYS_SET_TID_ADDRESS = 96 + SYS_UNSHARE = 97 + SYS_FUTEX = 98 + SYS_SET_ROBUST_LIST = 99 + SYS_GET_ROBUST_LIST = 100 + SYS_NANOSLEEP = 101 + SYS_GETITIMER = 102 + SYS_SETITIMER = 103 + SYS_KEXEC_LOAD = 104 + SYS_INIT_MODULE = 105 + SYS_DELETE_MODULE = 106 + SYS_TIMER_CREATE = 107 + SYS_TIMER_GETTIME = 108 + SYS_TIMER_GETOVERRUN = 109 + SYS_TIMER_SETTIME = 110 + SYS_TIMER_DELETE = 111 + SYS_CLOCK_SETTIME = 112 + SYS_CLOCK_GETTIME = 113 + SYS_CLOCK_GETRES = 114 + SYS_CLOCK_NANOSLEEP = 115 + SYS_SYSLOG = 116 + SYS_PTRACE = 117 + SYS_SCHED_SETPARAM = 118 + SYS_SCHED_SETSCHEDULER = 119 + SYS_SCHED_GETSCHEDULER = 120 + SYS_SCHED_GETPARAM = 121 + SYS_SCHED_SETAFFINITY = 122 + SYS_SCHED_GETAFFINITY = 123 + SYS_SCHED_YIELD = 124 + SYS_SCHED_GET_PRIORITY_MAX = 125 + SYS_SCHED_GET_PRIORITY_MIN = 126 + SYS_SCHED_RR_GET_INTERVAL = 127 + SYS_RESTART_SYSCALL = 128 + SYS_KILL = 129 + SYS_TKILL = 130 + SYS_TGKILL = 131 + SYS_SIGALTSTACK = 132 + SYS_RT_SIGSUSPEND = 133 + SYS_RT_SIGACTION = 134 + SYS_RT_SIGPROCMASK = 135 + SYS_RT_SIGPENDING = 136 + SYS_RT_SIGTIMEDWAIT = 137 + SYS_RT_SIGQUEUEINFO = 138 + SYS_RT_SIGRETURN = 139 + SYS_SETPRIORITY = 140 + SYS_GETPRIORITY = 141 + SYS_REBOOT = 142 + SYS_SETREGID = 143 + SYS_SETGID = 144 + SYS_SETREUID = 145 + SYS_SETUID = 146 + SYS_SETRESUID = 147 + SYS_GETRESUID = 148 + SYS_SETRESGID = 149 + SYS_GETRESGID = 150 + SYS_SETFSUID = 151 + SYS_SETFSGID = 152 + SYS_TIMES = 153 + SYS_SETPGID = 154 + SYS_GETPGID = 155 + SYS_GETSID = 156 + SYS_SETSID = 157 + SYS_GETGROUPS = 158 + SYS_SETGROUPS = 159 + SYS_UNAME = 160 + SYS_SETHOSTNAME = 161 + SYS_SETDOMAINNAME = 162 + SYS_GETRLIMIT = 163 + SYS_SETRLIMIT = 164 + SYS_GETRUSAGE = 165 + SYS_UMASK = 166 + SYS_PRCTL = 167 + SYS_GETCPU = 168 + SYS_GETTIMEOFDAY = 169 + SYS_SETTIMEOFDAY = 170 + SYS_ADJTIMEX = 171 + SYS_GETPID = 172 + SYS_GETPPID = 173 + SYS_GETUID = 174 + SYS_GETEUID = 175 + SYS_GETGID = 176 + SYS_GETEGID = 177 + SYS_GETTID = 178 + SYS_SYSINFO = 179 + SYS_MQ_OPEN = 180 + SYS_MQ_UNLINK = 181 + SYS_MQ_TIMEDSEND = 182 + SYS_MQ_TIMEDRECEIVE = 183 + SYS_MQ_NOTIFY = 184 + SYS_MQ_GETSETATTR = 185 + SYS_MSGGET = 186 + SYS_MSGCTL = 187 + SYS_MSGRCV = 188 + SYS_MSGSND = 189 + SYS_SEMGET = 190 + SYS_SEMCTL = 191 + SYS_SEMTIMEDOP = 192 + SYS_SEMOP = 193 + SYS_SHMGET = 194 + SYS_SHMCTL = 195 + SYS_SHMAT = 196 + SYS_SHMDT = 197 + SYS_SOCKET = 198 + SYS_SOCKETPAIR = 199 + SYS_BIND = 200 + SYS_LISTEN = 201 + SYS_ACCEPT = 202 + SYS_CONNECT = 203 + SYS_GETSOCKNAME = 204 + SYS_GETPEERNAME = 205 + SYS_SENDTO = 206 + SYS_RECVFROM = 207 + SYS_SETSOCKOPT = 208 + SYS_GETSOCKOPT = 209 + SYS_SHUTDOWN = 210 + SYS_SENDMSG = 211 + SYS_RECVMSG = 212 + SYS_READAHEAD = 213 + SYS_BRK = 214 + SYS_MUNMAP = 215 + SYS_MREMAP = 216 + SYS_ADD_KEY = 217 + SYS_REQUEST_KEY = 218 + SYS_KEYCTL = 219 + SYS_CLONE = 220 + SYS_EXECVE = 221 + SYS_MMAP = 222 + SYS_FADVISE64 = 223 + SYS_SWAPON = 224 + SYS_SWAPOFF = 225 + SYS_MPROTECT = 226 + SYS_MSYNC = 227 + SYS_MLOCK = 228 + SYS_MUNLOCK = 229 + SYS_MLOCKALL = 230 + SYS_MUNLOCKALL = 231 + SYS_MINCORE = 232 + SYS_MADVISE = 233 + SYS_REMAP_FILE_PAGES = 234 + SYS_MBIND = 235 + SYS_GET_MEMPOLICY = 236 + SYS_SET_MEMPOLICY = 237 + SYS_MIGRATE_PAGES = 238 + SYS_MOVE_PAGES = 239 + SYS_RT_TGSIGQUEUEINFO = 240 + SYS_PERF_EVENT_OPEN = 241 + SYS_ACCEPT4 = 242 + SYS_RECVMMSG = 243 + SYS_ARCH_SPECIFIC_SYSCALL = 244 + SYS_WAIT4 = 260 + SYS_PRLIMIT64 = 261 + SYS_FANOTIFY_INIT = 262 + SYS_FANOTIFY_MARK = 263 + SYS_NAME_TO_HANDLE_AT = 264 + SYS_OPEN_BY_HANDLE_AT = 265 + SYS_CLOCK_ADJTIME = 266 + SYS_SYNCFS = 267 + SYS_SETNS = 268 + SYS_SENDMMSG = 269 + SYS_PROCESS_VM_READV = 270 + SYS_PROCESS_VM_WRITEV = 271 + SYS_KCMP = 272 + SYS_FINIT_MODULE = 273 + SYS_SCHED_SETATTR = 274 + SYS_SCHED_GETATTR = 275 + SYS_RENAMEAT2 = 276 + SYS_SECCOMP = 277 + SYS_GETRANDOM = 278 + SYS_MEMFD_CREATE = 279 + SYS_BPF = 280 + SYS_EXECVEAT = 281 + SYS_USERFAULTFD = 282 + SYS_MEMBARRIER = 283 + SYS_MLOCK2 = 284 + SYS_COPY_FILE_RANGE = 285 + SYS_PREADV2 = 286 + SYS_PWRITEV2 = 287 + SYS_PKEY_MPROTECT = 288 + SYS_PKEY_ALLOC = 289 + SYS_PKEY_FREE = 290 + SYS_STATX = 291 + SYS_IO_PGETEVENTS = 292 +) diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_386.go b/vendor/golang.org/x/sys/unix/ztypes_linux_386.go index cb3729e..1944dfb 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_386.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_386.go @@ -510,6 +510,13 @@ const ( RTA_FLOW = 0xb RTA_CACHEINFO = 0xc RTA_TABLE = 0xf + RTA_MARK = 0x10 + RTA_MFC_STATS = 0x11 + RTA_VIA = 0x12 + RTA_NEWDST = 0x13 + RTA_PREF = 0x14 + RTA_ENCAP_TYPE = 0x15 + RTA_ENCAP = 0x16 RTN_UNSPEC = 0x0 RTN_UNICAST = 0x1 RTN_LOCAL = 0x2 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_amd64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_amd64.go index 0f3c0fb..dd09289 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_amd64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_amd64.go @@ -514,6 +514,13 @@ const ( RTA_FLOW = 0xb RTA_CACHEINFO = 0xc RTA_TABLE = 0xf + RTA_MARK = 0x10 + RTA_MFC_STATS = 0x11 + RTA_VIA = 0x12 + RTA_NEWDST = 0x13 + RTA_PREF = 0x14 + RTA_ENCAP_TYPE = 0x15 + RTA_ENCAP = 0x16 RTN_UNSPEC = 0x0 RTN_UNICAST = 0x1 RTN_LOCAL = 0x2 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_arm.go b/vendor/golang.org/x/sys/unix/ztypes_linux_arm.go index bd534da..d9e844d 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_arm.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_arm.go @@ -513,6 +513,13 @@ const ( RTA_FLOW = 0xb RTA_CACHEINFO = 0xc RTA_TABLE = 0xf + RTA_MARK = 0x10 + RTA_MFC_STATS = 0x11 + RTA_VIA = 0x12 + RTA_NEWDST = 0x13 + RTA_PREF = 0x14 + RTA_ENCAP_TYPE = 0x15 + RTA_ENCAP = 0x16 RTN_UNSPEC = 0x0 RTN_UNICAST = 0x1 RTN_LOCAL = 0x2 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_arm64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_arm64.go index 3a72fd9..fd2471a 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_arm64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_arm64.go @@ -515,6 +515,13 @@ const ( RTA_FLOW = 0xb RTA_CACHEINFO = 0xc RTA_TABLE = 0xf + RTA_MARK = 0x10 + RTA_MFC_STATS = 0x11 + RTA_VIA = 0x12 + RTA_NEWDST = 0x13 + RTA_PREF = 0x14 + RTA_ENCAP_TYPE = 0x15 + RTA_ENCAP = 0x16 RTN_UNSPEC = 0x0 RTN_UNICAST = 0x1 RTN_LOCAL = 0x2 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_mips.go b/vendor/golang.org/x/sys/unix/ztypes_linux_mips.go index cd360b2..89218d9 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_mips.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_mips.go @@ -511,6 +511,13 @@ const ( RTA_FLOW = 0xb RTA_CACHEINFO = 0xc RTA_TABLE = 0xf + RTA_MARK = 0x10 + RTA_MFC_STATS = 0x11 + RTA_VIA = 0x12 + RTA_NEWDST = 0x13 + RTA_PREF = 0x14 + RTA_ENCAP_TYPE = 0x15 + RTA_ENCAP = 0x16 RTN_UNSPEC = 0x0 RTN_UNICAST = 0x1 RTN_LOCAL = 0x2 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_mips64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_mips64.go index d35ec60..0599039 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_mips64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_mips64.go @@ -515,6 +515,13 @@ const ( RTA_FLOW = 0xb RTA_CACHEINFO = 0xc RTA_TABLE = 0xf + RTA_MARK = 0x10 + RTA_MFC_STATS = 0x11 + RTA_VIA = 0x12 + RTA_NEWDST = 0x13 + RTA_PREF = 0x14 + RTA_ENCAP_TYPE = 0x15 + RTA_ENCAP = 0x16 RTN_UNSPEC = 0x0 RTN_UNICAST = 0x1 RTN_LOCAL = 0x2 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_mips64le.go b/vendor/golang.org/x/sys/unix/ztypes_linux_mips64le.go index 0f49930..c933cea 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_mips64le.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_mips64le.go @@ -515,6 +515,13 @@ const ( RTA_FLOW = 0xb RTA_CACHEINFO = 0xc RTA_TABLE = 0xf + RTA_MARK = 0x10 + RTA_MFC_STATS = 0x11 + RTA_VIA = 0x12 + RTA_NEWDST = 0x13 + RTA_PREF = 0x14 + RTA_ENCAP_TYPE = 0x15 + RTA_ENCAP = 0x16 RTN_UNSPEC = 0x0 RTN_UNICAST = 0x1 RTN_LOCAL = 0x2 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_mipsle.go b/vendor/golang.org/x/sys/unix/ztypes_linux_mipsle.go index 55f97c5..92d358a 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_mipsle.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_mipsle.go @@ -511,6 +511,13 @@ const ( RTA_FLOW = 0xb RTA_CACHEINFO = 0xc RTA_TABLE = 0xf + RTA_MARK = 0x10 + RTA_MFC_STATS = 0x11 + RTA_VIA = 0x12 + RTA_NEWDST = 0x13 + RTA_PREF = 0x14 + RTA_ENCAP_TYPE = 0x15 + RTA_ENCAP = 0x16 RTN_UNSPEC = 0x0 RTN_UNICAST = 0x1 RTN_LOCAL = 0x2 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64.go index f1d4264..2dbda84 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64.go @@ -516,6 +516,13 @@ const ( RTA_FLOW = 0xb RTA_CACHEINFO = 0xc RTA_TABLE = 0xf + RTA_MARK = 0x10 + RTA_MFC_STATS = 0x11 + RTA_VIA = 0x12 + RTA_NEWDST = 0x13 + RTA_PREF = 0x14 + RTA_ENCAP_TYPE = 0x15 + RTA_ENCAP = 0x16 RTN_UNSPEC = 0x0 RTN_UNICAST = 0x1 RTN_LOCAL = 0x2 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64le.go b/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64le.go index 90ab1f7..b1d2357 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64le.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64le.go @@ -516,6 +516,13 @@ const ( RTA_FLOW = 0xb RTA_CACHEINFO = 0xc RTA_TABLE = 0xf + RTA_MARK = 0x10 + RTA_MFC_STATS = 0x11 + RTA_VIA = 0x12 + RTA_NEWDST = 0x13 + RTA_PREF = 0x14 + RTA_ENCAP_TYPE = 0x15 + RTA_ENCAP = 0x16 RTN_UNSPEC = 0x0 RTN_UNICAST = 0x1 RTN_LOCAL = 0x2 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_riscv64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_riscv64.go new file mode 100644 index 0000000..0a34ccd --- /dev/null +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_riscv64.go @@ -0,0 +1,1919 @@ +// cgo -godefs -- -Wall -Werror -static -I/tmp/include linux/types.go | go run mkpost.go +// Code generated by the command above; see README.md. DO NOT EDIT. + +// +build riscv64,linux + +package unix + +const ( + sizeofPtr = 0x8 + sizeofShort = 0x2 + sizeofInt = 0x4 + sizeofLong = 0x8 + sizeofLongLong = 0x8 + PathMax = 0x1000 +) + +type ( + _C_short int16 + _C_int int32 + _C_long int64 + _C_long_long int64 +) + +type Timespec struct { + Sec int64 + Nsec int64 +} + +type Timeval struct { + Sec int64 + Usec int64 +} + +type Timex struct { + Modes uint32 + _ [4]byte + Offset int64 + Freq int64 + Maxerror int64 + Esterror int64 + Status int32 + _ [4]byte + Constant int64 + Precision int64 + Tolerance int64 + Time Timeval + Tick int64 + Ppsfreq int64 + Jitter int64 + Shift int32 + _ [4]byte + Stabil int64 + Jitcnt int64 + Calcnt int64 + Errcnt int64 + Stbcnt int64 + Tai int32 + _ [44]byte +} + +type Time_t int64 + +type Tms struct { + Utime int64 + Stime int64 + Cutime int64 + Cstime int64 +} + +type Utimbuf struct { + Actime int64 + Modtime int64 +} + +type Rusage struct { + Utime Timeval + Stime Timeval + Maxrss int64 + Ixrss int64 + Idrss int64 + Isrss int64 + Minflt int64 + Majflt int64 + Nswap int64 + Inblock int64 + Oublock int64 + Msgsnd int64 + Msgrcv int64 + Nsignals int64 + Nvcsw int64 + Nivcsw int64 +} + +type Rlimit struct { + Cur uint64 + Max uint64 +} + +type _Gid_t uint32 + +type Stat_t struct { + Dev uint64 + Ino uint64 + Mode uint32 + Nlink uint32 + Uid uint32 + Gid uint32 + Rdev uint64 + _ uint64 + Size int64 + Blksize int32 + _ int32 + Blocks int64 + Atim Timespec + Mtim Timespec + Ctim Timespec + _ [2]int32 +} + +type StatxTimestamp struct { + Sec int64 + Nsec uint32 + _ int32 +} + +type Statx_t struct { + Mask uint32 + Blksize uint32 + Attributes uint64 + Nlink uint32 + Uid uint32 + Gid uint32 + Mode uint16 + _ [1]uint16 + Ino uint64 + Size uint64 + Blocks uint64 + Attributes_mask uint64 + Atime StatxTimestamp + Btime StatxTimestamp + Ctime StatxTimestamp + Mtime StatxTimestamp + Rdev_major uint32 + Rdev_minor uint32 + Dev_major uint32 + Dev_minor uint32 + _ [14]uint64 +} + +type Dirent struct { + Ino uint64 + Off int64 + Reclen uint16 + Type uint8 + Name [256]uint8 + _ [5]byte +} + +type Fsid struct { + Val [2]int32 +} + +type Flock_t struct { + Type int16 + Whence int16 + _ [4]byte + Start int64 + Len int64 + Pid int32 + _ [4]byte +} + +type FscryptPolicy struct { + Version uint8 + Contents_encryption_mode uint8 + Filenames_encryption_mode uint8 + Flags uint8 + Master_key_descriptor [8]uint8 +} + +type FscryptKey struct { + Mode uint32 + Raw [64]uint8 + Size uint32 +} + +type KeyctlDHParams struct { + Private int32 + Prime int32 + Base int32 +} + +const ( + FADV_NORMAL = 0x0 + FADV_RANDOM = 0x1 + FADV_SEQUENTIAL = 0x2 + FADV_WILLNEED = 0x3 + FADV_DONTNEED = 0x4 + FADV_NOREUSE = 0x5 +) + +type RawSockaddrInet4 struct { + Family uint16 + Port uint16 + Addr [4]byte /* in_addr */ + Zero [8]uint8 +} + +type RawSockaddrInet6 struct { + Family uint16 + Port uint16 + Flowinfo uint32 + Addr [16]byte /* in6_addr */ + Scope_id uint32 +} + +type RawSockaddrUnix struct { + Family uint16 + Path [108]uint8 +} + +type RawSockaddrLinklayer struct { + Family uint16 + Protocol uint16 + Ifindex int32 + Hatype uint16 + Pkttype uint8 + Halen uint8 + Addr [8]uint8 +} + +type RawSockaddrNetlink struct { + Family uint16 + Pad uint16 + Pid uint32 + Groups uint32 +} + +type RawSockaddrHCI struct { + Family uint16 + Dev uint16 + Channel uint16 +} + +type RawSockaddrL2 struct { + Family uint16 + Psm uint16 + Bdaddr [6]uint8 + Cid uint16 + Bdaddr_type uint8 + _ [1]byte +} + +type RawSockaddrRFCOMM struct { + Family uint16 + Bdaddr [6]uint8 + Channel uint8 + _ [1]byte +} + +type RawSockaddrCAN struct { + Family uint16 + _ [2]byte + Ifindex int32 + Addr [8]byte +} + +type RawSockaddrALG struct { + Family uint16 + Type [14]uint8 + Feat uint32 + Mask uint32 + Name [64]uint8 +} + +type RawSockaddrVM struct { + Family uint16 + Reserved1 uint16 + Port uint32 + Cid uint32 + Zero [4]uint8 +} + +type RawSockaddr struct { + Family uint16 + Data [14]uint8 +} + +type RawSockaddrAny struct { + Addr RawSockaddr + Pad [96]uint8 +} + +type _Socklen uint32 + +type Linger struct { + Onoff int32 + Linger int32 +} + +type Iovec struct { + Base *byte + Len uint64 +} + +type IPMreq struct { + Multiaddr [4]byte /* in_addr */ + Interface [4]byte /* in_addr */ +} + +type IPMreqn struct { + Multiaddr [4]byte /* in_addr */ + Address [4]byte /* in_addr */ + Ifindex int32 +} + +type IPv6Mreq struct { + Multiaddr [16]byte /* in6_addr */ + Interface uint32 +} + +type PacketMreq struct { + Ifindex int32 + Type uint16 + Alen uint16 + Address [8]uint8 +} + +type Msghdr struct { + Name *byte + Namelen uint32 + _ [4]byte + Iov *Iovec + Iovlen uint64 + Control *byte + Controllen uint64 + Flags int32 + _ [4]byte +} + +type Cmsghdr struct { + Len uint64 + Level int32 + Type int32 +} + +type Inet4Pktinfo struct { + Ifindex int32 + Spec_dst [4]byte /* in_addr */ + Addr [4]byte /* in_addr */ +} + +type Inet6Pktinfo struct { + Addr [16]byte /* in6_addr */ + Ifindex uint32 +} + +type IPv6MTUInfo struct { + Addr RawSockaddrInet6 + Mtu uint32 +} + +type ICMPv6Filter struct { + Data [8]uint32 +} + +type Ucred struct { + Pid int32 + Uid uint32 + Gid uint32 +} + +type TCPInfo struct { + State uint8 + Ca_state uint8 + Retransmits uint8 + Probes uint8 + Backoff uint8 + Options uint8 + _ [2]byte + Rto uint32 + Ato uint32 + Snd_mss uint32 + Rcv_mss uint32 + Unacked uint32 + Sacked uint32 + Lost uint32 + Retrans uint32 + Fackets uint32 + Last_data_sent uint32 + Last_ack_sent uint32 + Last_data_recv uint32 + Last_ack_recv uint32 + Pmtu uint32 + Rcv_ssthresh uint32 + Rtt uint32 + Rttvar uint32 + Snd_ssthresh uint32 + Snd_cwnd uint32 + Advmss uint32 + Reordering uint32 + Rcv_rtt uint32 + Rcv_space uint32 + Total_retrans uint32 +} + +const ( + SizeofSockaddrInet4 = 0x10 + SizeofSockaddrInet6 = 0x1c + SizeofSockaddrAny = 0x70 + SizeofSockaddrUnix = 0x6e + SizeofSockaddrLinklayer = 0x14 + SizeofSockaddrNetlink = 0xc + SizeofSockaddrHCI = 0x6 + SizeofSockaddrL2 = 0xe + SizeofSockaddrRFCOMM = 0xa + SizeofSockaddrCAN = 0x10 + SizeofSockaddrALG = 0x58 + SizeofSockaddrVM = 0x10 + SizeofLinger = 0x8 + SizeofIovec = 0x10 + SizeofIPMreq = 0x8 + SizeofIPMreqn = 0xc + SizeofIPv6Mreq = 0x14 + SizeofPacketMreq = 0x10 + SizeofMsghdr = 0x38 + SizeofCmsghdr = 0x10 + SizeofInet4Pktinfo = 0xc + SizeofInet6Pktinfo = 0x14 + SizeofIPv6MTUInfo = 0x20 + SizeofICMPv6Filter = 0x20 + SizeofUcred = 0xc + SizeofTCPInfo = 0x68 +) + +const ( + IFA_UNSPEC = 0x0 + IFA_ADDRESS = 0x1 + IFA_LOCAL = 0x2 + IFA_LABEL = 0x3 + IFA_BROADCAST = 0x4 + IFA_ANYCAST = 0x5 + IFA_CACHEINFO = 0x6 + IFA_MULTICAST = 0x7 + IFLA_UNSPEC = 0x0 + IFLA_ADDRESS = 0x1 + IFLA_BROADCAST = 0x2 + IFLA_IFNAME = 0x3 + IFLA_INFO_KIND = 0x1 + IFLA_MTU = 0x4 + IFLA_LINK = 0x5 + IFLA_QDISC = 0x6 + IFLA_STATS = 0x7 + IFLA_COST = 0x8 + IFLA_PRIORITY = 0x9 + IFLA_MASTER = 0xa + IFLA_WIRELESS = 0xb + IFLA_PROTINFO = 0xc + IFLA_TXQLEN = 0xd + IFLA_MAP = 0xe + IFLA_WEIGHT = 0xf + IFLA_OPERSTATE = 0x10 + IFLA_LINKMODE = 0x11 + IFLA_LINKINFO = 0x12 + IFLA_NET_NS_PID = 0x13 + IFLA_IFALIAS = 0x14 + IFLA_NUM_VF = 0x15 + IFLA_VFINFO_LIST = 0x16 + IFLA_STATS64 = 0x17 + IFLA_VF_PORTS = 0x18 + IFLA_PORT_SELF = 0x19 + IFLA_AF_SPEC = 0x1a + IFLA_GROUP = 0x1b + IFLA_NET_NS_FD = 0x1c + IFLA_EXT_MASK = 0x1d + IFLA_PROMISCUITY = 0x1e + IFLA_NUM_TX_QUEUES = 0x1f + IFLA_NUM_RX_QUEUES = 0x20 + IFLA_CARRIER = 0x21 + IFLA_PHYS_PORT_ID = 0x22 + IFLA_CARRIER_CHANGES = 0x23 + IFLA_PHYS_SWITCH_ID = 0x24 + IFLA_LINK_NETNSID = 0x25 + IFLA_PHYS_PORT_NAME = 0x26 + IFLA_PROTO_DOWN = 0x27 + IFLA_GSO_MAX_SEGS = 0x28 + IFLA_GSO_MAX_SIZE = 0x29 + IFLA_PAD = 0x2a + IFLA_XDP = 0x2b + IFLA_EVENT = 0x2c + IFLA_NEW_NETNSID = 0x2d + IFLA_IF_NETNSID = 0x2e + IFLA_MAX = 0x31 + RT_SCOPE_UNIVERSE = 0x0 + RT_SCOPE_SITE = 0xc8 + RT_SCOPE_LINK = 0xfd + RT_SCOPE_HOST = 0xfe + RT_SCOPE_NOWHERE = 0xff + RT_TABLE_UNSPEC = 0x0 + RT_TABLE_COMPAT = 0xfc + RT_TABLE_DEFAULT = 0xfd + RT_TABLE_MAIN = 0xfe + RT_TABLE_LOCAL = 0xff + RT_TABLE_MAX = 0xffffffff + RTA_UNSPEC = 0x0 + RTA_DST = 0x1 + RTA_SRC = 0x2 + RTA_IIF = 0x3 + RTA_OIF = 0x4 + RTA_GATEWAY = 0x5 + RTA_PRIORITY = 0x6 + RTA_PREFSRC = 0x7 + RTA_METRICS = 0x8 + RTA_MULTIPATH = 0x9 + RTA_FLOW = 0xb + RTA_CACHEINFO = 0xc + RTA_TABLE = 0xf + RTA_MARK = 0x10 + RTA_MFC_STATS = 0x11 + RTA_VIA = 0x12 + RTA_NEWDST = 0x13 + RTA_PREF = 0x14 + RTA_ENCAP_TYPE = 0x15 + RTA_ENCAP = 0x16 + RTN_UNSPEC = 0x0 + RTN_UNICAST = 0x1 + RTN_LOCAL = 0x2 + RTN_BROADCAST = 0x3 + RTN_ANYCAST = 0x4 + RTN_MULTICAST = 0x5 + RTN_BLACKHOLE = 0x6 + RTN_UNREACHABLE = 0x7 + RTN_PROHIBIT = 0x8 + RTN_THROW = 0x9 + RTN_NAT = 0xa + RTN_XRESOLVE = 0xb + RTNLGRP_NONE = 0x0 + RTNLGRP_LINK = 0x1 + RTNLGRP_NOTIFY = 0x2 + RTNLGRP_NEIGH = 0x3 + RTNLGRP_TC = 0x4 + RTNLGRP_IPV4_IFADDR = 0x5 + RTNLGRP_IPV4_MROUTE = 0x6 + RTNLGRP_IPV4_ROUTE = 0x7 + RTNLGRP_IPV4_RULE = 0x8 + RTNLGRP_IPV6_IFADDR = 0x9 + RTNLGRP_IPV6_MROUTE = 0xa + RTNLGRP_IPV6_ROUTE = 0xb + RTNLGRP_IPV6_IFINFO = 0xc + RTNLGRP_IPV6_PREFIX = 0x12 + RTNLGRP_IPV6_RULE = 0x13 + RTNLGRP_ND_USEROPT = 0x14 + SizeofNlMsghdr = 0x10 + SizeofNlMsgerr = 0x14 + SizeofRtGenmsg = 0x1 + SizeofNlAttr = 0x4 + SizeofRtAttr = 0x4 + SizeofIfInfomsg = 0x10 + SizeofIfAddrmsg = 0x8 + SizeofRtMsg = 0xc + SizeofRtNexthop = 0x8 +) + +type NlMsghdr struct { + Len uint32 + Type uint16 + Flags uint16 + Seq uint32 + Pid uint32 +} + +type NlMsgerr struct { + Error int32 + Msg NlMsghdr +} + +type RtGenmsg struct { + Family uint8 +} + +type NlAttr struct { + Len uint16 + Type uint16 +} + +type RtAttr struct { + Len uint16 + Type uint16 +} + +type IfInfomsg struct { + Family uint8 + _ uint8 + Type uint16 + Index int32 + Flags uint32 + Change uint32 +} + +type IfAddrmsg struct { + Family uint8 + Prefixlen uint8 + Flags uint8 + Scope uint8 + Index uint32 +} + +type RtMsg struct { + Family uint8 + Dst_len uint8 + Src_len uint8 + Tos uint8 + Table uint8 + Protocol uint8 + Scope uint8 + Type uint8 + Flags uint32 +} + +type RtNexthop struct { + Len uint16 + Flags uint8 + Hops uint8 + Ifindex int32 +} + +const ( + SizeofSockFilter = 0x8 + SizeofSockFprog = 0x10 +) + +type SockFilter struct { + Code uint16 + Jt uint8 + Jf uint8 + K uint32 +} + +type SockFprog struct { + Len uint16 + _ [6]byte + Filter *SockFilter +} + +type InotifyEvent struct { + Wd int32 + Mask uint32 + Cookie uint32 + Len uint32 +} + +const SizeofInotifyEvent = 0x10 + +type PtraceRegs struct { + Pc uint64 + Ra uint64 + Sp uint64 + Gp uint64 + Tp uint64 + T0 uint64 + T1 uint64 + T2 uint64 + S0 uint64 + S1 uint64 + A0 uint64 + A1 uint64 + A2 uint64 + A3 uint64 + A4 uint64 + A5 uint64 + A6 uint64 + A7 uint64 + S2 uint64 + S3 uint64 + S4 uint64 + S5 uint64 + S6 uint64 + S7 uint64 + S8 uint64 + S9 uint64 + S10 uint64 + S11 uint64 + T3 uint64 + T4 uint64 + T5 uint64 + T6 uint64 +} + +type FdSet struct { + Bits [16]int64 +} + +type Sysinfo_t struct { + Uptime int64 + Loads [3]uint64 + Totalram uint64 + Freeram uint64 + Sharedram uint64 + Bufferram uint64 + Totalswap uint64 + Freeswap uint64 + Procs uint16 + Pad uint16 + _ [4]byte + Totalhigh uint64 + Freehigh uint64 + Unit uint32 + _ [0]uint8 + _ [4]byte +} + +type Utsname struct { + Sysname [65]byte + Nodename [65]byte + Release [65]byte + Version [65]byte + Machine [65]byte + Domainname [65]byte +} + +type Ustat_t struct { + Tfree int32 + _ [4]byte + Tinode uint64 + Fname [6]uint8 + Fpack [6]uint8 + _ [4]byte +} + +type EpollEvent struct { + Events uint32 + Fd int32 + Pad int32 +} + +const ( + AT_EMPTY_PATH = 0x1000 + AT_FDCWD = -0x64 + AT_NO_AUTOMOUNT = 0x800 + AT_REMOVEDIR = 0x200 + + AT_STATX_SYNC_AS_STAT = 0x0 + AT_STATX_FORCE_SYNC = 0x2000 + AT_STATX_DONT_SYNC = 0x4000 + + AT_SYMLINK_FOLLOW = 0x400 + AT_SYMLINK_NOFOLLOW = 0x100 + + AT_EACCESS = 0x200 +) + +type PollFd struct { + Fd int32 + Events int16 + Revents int16 +} + +const ( + POLLIN = 0x1 + POLLPRI = 0x2 + POLLOUT = 0x4 + POLLRDHUP = 0x2000 + POLLERR = 0x8 + POLLHUP = 0x10 + POLLNVAL = 0x20 +) + +type Sigset_t struct { + Val [16]uint64 +} + +const RNDGETENTCNT = 0x80045200 + +const PERF_IOC_FLAG_GROUP = 0x1 + +type Termios struct { + Iflag uint32 + Oflag uint32 + Cflag uint32 + Lflag uint32 + Line uint8 + Cc [19]uint8 + Ispeed uint32 + Ospeed uint32 +} + +type Winsize struct { + Row uint16 + Col uint16 + Xpixel uint16 + Ypixel uint16 +} + +type Taskstats struct { + Version uint16 + _ [2]byte + Ac_exitcode uint32 + Ac_flag uint8 + Ac_nice uint8 + _ [6]byte + Cpu_count uint64 + Cpu_delay_total uint64 + Blkio_count uint64 + Blkio_delay_total uint64 + Swapin_count uint64 + Swapin_delay_total uint64 + Cpu_run_real_total uint64 + Cpu_run_virtual_total uint64 + Ac_comm [32]uint8 + Ac_sched uint8 + Ac_pad [3]uint8 + _ [4]byte + Ac_uid uint32 + Ac_gid uint32 + Ac_pid uint32 + Ac_ppid uint32 + Ac_btime uint32 + _ [4]byte + Ac_etime uint64 + Ac_utime uint64 + Ac_stime uint64 + Ac_minflt uint64 + Ac_majflt uint64 + Coremem uint64 + Virtmem uint64 + Hiwater_rss uint64 + Hiwater_vm uint64 + Read_char uint64 + Write_char uint64 + Read_syscalls uint64 + Write_syscalls uint64 + Read_bytes uint64 + Write_bytes uint64 + Cancelled_write_bytes uint64 + Nvcsw uint64 + Nivcsw uint64 + Ac_utimescaled uint64 + Ac_stimescaled uint64 + Cpu_scaled_run_real_total uint64 + Freepages_count uint64 + Freepages_delay_total uint64 +} + +const ( + TASKSTATS_CMD_UNSPEC = 0x0 + TASKSTATS_CMD_GET = 0x1 + TASKSTATS_CMD_NEW = 0x2 + TASKSTATS_TYPE_UNSPEC = 0x0 + TASKSTATS_TYPE_PID = 0x1 + TASKSTATS_TYPE_TGID = 0x2 + TASKSTATS_TYPE_STATS = 0x3 + TASKSTATS_TYPE_AGGR_PID = 0x4 + TASKSTATS_TYPE_AGGR_TGID = 0x5 + TASKSTATS_TYPE_NULL = 0x6 + TASKSTATS_CMD_ATTR_UNSPEC = 0x0 + TASKSTATS_CMD_ATTR_PID = 0x1 + TASKSTATS_CMD_ATTR_TGID = 0x2 + TASKSTATS_CMD_ATTR_REGISTER_CPUMASK = 0x3 + TASKSTATS_CMD_ATTR_DEREGISTER_CPUMASK = 0x4 +) + +type CGroupStats struct { + Sleeping uint64 + Running uint64 + Stopped uint64 + Uninterruptible uint64 + Io_wait uint64 +} + +const ( + CGROUPSTATS_CMD_UNSPEC = 0x3 + CGROUPSTATS_CMD_GET = 0x4 + CGROUPSTATS_CMD_NEW = 0x5 + CGROUPSTATS_TYPE_UNSPEC = 0x0 + CGROUPSTATS_TYPE_CGROUP_STATS = 0x1 + CGROUPSTATS_CMD_ATTR_UNSPEC = 0x0 + CGROUPSTATS_CMD_ATTR_FD = 0x1 +) + +type Genlmsghdr struct { + Cmd uint8 + Version uint8 + Reserved uint16 +} + +const ( + CTRL_CMD_UNSPEC = 0x0 + CTRL_CMD_NEWFAMILY = 0x1 + CTRL_CMD_DELFAMILY = 0x2 + CTRL_CMD_GETFAMILY = 0x3 + CTRL_CMD_NEWOPS = 0x4 + CTRL_CMD_DELOPS = 0x5 + CTRL_CMD_GETOPS = 0x6 + CTRL_CMD_NEWMCAST_GRP = 0x7 + CTRL_CMD_DELMCAST_GRP = 0x8 + CTRL_CMD_GETMCAST_GRP = 0x9 + CTRL_ATTR_UNSPEC = 0x0 + CTRL_ATTR_FAMILY_ID = 0x1 + CTRL_ATTR_FAMILY_NAME = 0x2 + CTRL_ATTR_VERSION = 0x3 + CTRL_ATTR_HDRSIZE = 0x4 + CTRL_ATTR_MAXATTR = 0x5 + CTRL_ATTR_OPS = 0x6 + CTRL_ATTR_MCAST_GROUPS = 0x7 + CTRL_ATTR_OP_UNSPEC = 0x0 + CTRL_ATTR_OP_ID = 0x1 + CTRL_ATTR_OP_FLAGS = 0x2 + CTRL_ATTR_MCAST_GRP_UNSPEC = 0x0 + CTRL_ATTR_MCAST_GRP_NAME = 0x1 + CTRL_ATTR_MCAST_GRP_ID = 0x2 +) + +type cpuMask uint64 + +const ( + _CPU_SETSIZE = 0x400 + _NCPUBITS = 0x40 +) + +const ( + BDADDR_BREDR = 0x0 + BDADDR_LE_PUBLIC = 0x1 + BDADDR_LE_RANDOM = 0x2 +) + +type PerfEventAttr struct { + Type uint32 + Size uint32 + Config uint64 + Sample uint64 + Sample_type uint64 + Read_format uint64 + Bits uint64 + Wakeup uint32 + Bp_type uint32 + Ext1 uint64 + Ext2 uint64 + Branch_sample_type uint64 + Sample_regs_user uint64 + Sample_stack_user uint32 + Clockid int32 + Sample_regs_intr uint64 + Aux_watermark uint32 + _ uint32 +} + +type PerfEventMmapPage struct { + Version uint32 + Compat_version uint32 + Lock uint32 + Index uint32 + Offset int64 + Time_enabled uint64 + Time_running uint64 + Capabilities uint64 + Pmc_width uint16 + Time_shift uint16 + Time_mult uint32 + Time_offset uint64 + Time_zero uint64 + Size uint32 + _ [948]uint8 + Data_head uint64 + Data_tail uint64 + Data_offset uint64 + Data_size uint64 + Aux_head uint64 + Aux_tail uint64 + Aux_offset uint64 + Aux_size uint64 +} + +const ( + PerfBitDisabled uint64 = CBitFieldMaskBit0 + PerfBitInherit = CBitFieldMaskBit1 + PerfBitPinned = CBitFieldMaskBit2 + PerfBitExclusive = CBitFieldMaskBit3 + PerfBitExcludeUser = CBitFieldMaskBit4 + PerfBitExcludeKernel = CBitFieldMaskBit5 + PerfBitExcludeHv = CBitFieldMaskBit6 + PerfBitExcludeIdle = CBitFieldMaskBit7 + PerfBitMmap = CBitFieldMaskBit8 + PerfBitComm = CBitFieldMaskBit9 + PerfBitFreq = CBitFieldMaskBit10 + PerfBitInheritStat = CBitFieldMaskBit11 + PerfBitEnableOnExec = CBitFieldMaskBit12 + PerfBitTask = CBitFieldMaskBit13 + PerfBitWatermark = CBitFieldMaskBit14 + PerfBitPreciseIPBit1 = CBitFieldMaskBit15 + PerfBitPreciseIPBit2 = CBitFieldMaskBit16 + PerfBitMmapData = CBitFieldMaskBit17 + PerfBitSampleIDAll = CBitFieldMaskBit18 + PerfBitExcludeHost = CBitFieldMaskBit19 + PerfBitExcludeGuest = CBitFieldMaskBit20 + PerfBitExcludeCallchainKernel = CBitFieldMaskBit21 + PerfBitExcludeCallchainUser = CBitFieldMaskBit22 + PerfBitMmap2 = CBitFieldMaskBit23 + PerfBitCommExec = CBitFieldMaskBit24 + PerfBitUseClockID = CBitFieldMaskBit25 + PerfBitContextSwitch = CBitFieldMaskBit26 +) + +const ( + PERF_TYPE_HARDWARE = 0x0 + PERF_TYPE_SOFTWARE = 0x1 + PERF_TYPE_TRACEPOINT = 0x2 + PERF_TYPE_HW_CACHE = 0x3 + PERF_TYPE_RAW = 0x4 + PERF_TYPE_BREAKPOINT = 0x5 + + PERF_COUNT_HW_CPU_CYCLES = 0x0 + PERF_COUNT_HW_INSTRUCTIONS = 0x1 + PERF_COUNT_HW_CACHE_REFERENCES = 0x2 + PERF_COUNT_HW_CACHE_MISSES = 0x3 + PERF_COUNT_HW_BRANCH_INSTRUCTIONS = 0x4 + PERF_COUNT_HW_BRANCH_MISSES = 0x5 + PERF_COUNT_HW_BUS_CYCLES = 0x6 + PERF_COUNT_HW_STALLED_CYCLES_FRONTEND = 0x7 + PERF_COUNT_HW_STALLED_CYCLES_BACKEND = 0x8 + PERF_COUNT_HW_REF_CPU_CYCLES = 0x9 + + PERF_COUNT_HW_CACHE_L1D = 0x0 + PERF_COUNT_HW_CACHE_L1I = 0x1 + PERF_COUNT_HW_CACHE_LL = 0x2 + PERF_COUNT_HW_CACHE_DTLB = 0x3 + PERF_COUNT_HW_CACHE_ITLB = 0x4 + PERF_COUNT_HW_CACHE_BPU = 0x5 + PERF_COUNT_HW_CACHE_NODE = 0x6 + + PERF_COUNT_HW_CACHE_OP_READ = 0x0 + PERF_COUNT_HW_CACHE_OP_WRITE = 0x1 + PERF_COUNT_HW_CACHE_OP_PREFETCH = 0x2 + + PERF_COUNT_HW_CACHE_RESULT_ACCESS = 0x0 + PERF_COUNT_HW_CACHE_RESULT_MISS = 0x1 + + PERF_COUNT_SW_CPU_CLOCK = 0x0 + PERF_COUNT_SW_TASK_CLOCK = 0x1 + PERF_COUNT_SW_PAGE_FAULTS = 0x2 + PERF_COUNT_SW_CONTEXT_SWITCHES = 0x3 + PERF_COUNT_SW_CPU_MIGRATIONS = 0x4 + PERF_COUNT_SW_PAGE_FAULTS_MIN = 0x5 + PERF_COUNT_SW_PAGE_FAULTS_MAJ = 0x6 + PERF_COUNT_SW_ALIGNMENT_FAULTS = 0x7 + PERF_COUNT_SW_EMULATION_FAULTS = 0x8 + PERF_COUNT_SW_DUMMY = 0x9 + + PERF_SAMPLE_IP = 0x1 + PERF_SAMPLE_TID = 0x2 + PERF_SAMPLE_TIME = 0x4 + PERF_SAMPLE_ADDR = 0x8 + PERF_SAMPLE_READ = 0x10 + PERF_SAMPLE_CALLCHAIN = 0x20 + PERF_SAMPLE_ID = 0x40 + PERF_SAMPLE_CPU = 0x80 + PERF_SAMPLE_PERIOD = 0x100 + PERF_SAMPLE_STREAM_ID = 0x200 + PERF_SAMPLE_RAW = 0x400 + PERF_SAMPLE_BRANCH_STACK = 0x800 + + PERF_SAMPLE_BRANCH_USER = 0x1 + PERF_SAMPLE_BRANCH_KERNEL = 0x2 + PERF_SAMPLE_BRANCH_HV = 0x4 + PERF_SAMPLE_BRANCH_ANY = 0x8 + PERF_SAMPLE_BRANCH_ANY_CALL = 0x10 + PERF_SAMPLE_BRANCH_ANY_RETURN = 0x20 + PERF_SAMPLE_BRANCH_IND_CALL = 0x40 + + PERF_FORMAT_TOTAL_TIME_ENABLED = 0x1 + PERF_FORMAT_TOTAL_TIME_RUNNING = 0x2 + PERF_FORMAT_ID = 0x4 + PERF_FORMAT_GROUP = 0x8 + + PERF_RECORD_MMAP = 0x1 + PERF_RECORD_LOST = 0x2 + PERF_RECORD_COMM = 0x3 + PERF_RECORD_EXIT = 0x4 + PERF_RECORD_THROTTLE = 0x5 + PERF_RECORD_UNTHROTTLE = 0x6 + PERF_RECORD_FORK = 0x7 + PERF_RECORD_READ = 0x8 + PERF_RECORD_SAMPLE = 0x9 + + PERF_CONTEXT_HV = -0x20 + PERF_CONTEXT_KERNEL = -0x80 + PERF_CONTEXT_USER = -0x200 + + PERF_CONTEXT_GUEST = -0x800 + PERF_CONTEXT_GUEST_KERNEL = -0x880 + PERF_CONTEXT_GUEST_USER = -0xa00 + + PERF_FLAG_FD_NO_GROUP = 0x1 + PERF_FLAG_FD_OUTPUT = 0x2 + PERF_FLAG_PID_CGROUP = 0x4 +) + +const ( + CBitFieldMaskBit0 = 0x1 + CBitFieldMaskBit1 = 0x2 + CBitFieldMaskBit2 = 0x4 + CBitFieldMaskBit3 = 0x8 + CBitFieldMaskBit4 = 0x10 + CBitFieldMaskBit5 = 0x20 + CBitFieldMaskBit6 = 0x40 + CBitFieldMaskBit7 = 0x80 + CBitFieldMaskBit8 = 0x100 + CBitFieldMaskBit9 = 0x200 + CBitFieldMaskBit10 = 0x400 + CBitFieldMaskBit11 = 0x800 + CBitFieldMaskBit12 = 0x1000 + CBitFieldMaskBit13 = 0x2000 + CBitFieldMaskBit14 = 0x4000 + CBitFieldMaskBit15 = 0x8000 + CBitFieldMaskBit16 = 0x10000 + CBitFieldMaskBit17 = 0x20000 + CBitFieldMaskBit18 = 0x40000 + CBitFieldMaskBit19 = 0x80000 + CBitFieldMaskBit20 = 0x100000 + CBitFieldMaskBit21 = 0x200000 + CBitFieldMaskBit22 = 0x400000 + CBitFieldMaskBit23 = 0x800000 + CBitFieldMaskBit24 = 0x1000000 + CBitFieldMaskBit25 = 0x2000000 + CBitFieldMaskBit26 = 0x4000000 + CBitFieldMaskBit27 = 0x8000000 + CBitFieldMaskBit28 = 0x10000000 + CBitFieldMaskBit29 = 0x20000000 + CBitFieldMaskBit30 = 0x40000000 + CBitFieldMaskBit31 = 0x80000000 + CBitFieldMaskBit32 = 0x100000000 + CBitFieldMaskBit33 = 0x200000000 + CBitFieldMaskBit34 = 0x400000000 + CBitFieldMaskBit35 = 0x800000000 + CBitFieldMaskBit36 = 0x1000000000 + CBitFieldMaskBit37 = 0x2000000000 + CBitFieldMaskBit38 = 0x4000000000 + CBitFieldMaskBit39 = 0x8000000000 + CBitFieldMaskBit40 = 0x10000000000 + CBitFieldMaskBit41 = 0x20000000000 + CBitFieldMaskBit42 = 0x40000000000 + CBitFieldMaskBit43 = 0x80000000000 + CBitFieldMaskBit44 = 0x100000000000 + CBitFieldMaskBit45 = 0x200000000000 + CBitFieldMaskBit46 = 0x400000000000 + CBitFieldMaskBit47 = 0x800000000000 + CBitFieldMaskBit48 = 0x1000000000000 + CBitFieldMaskBit49 = 0x2000000000000 + CBitFieldMaskBit50 = 0x4000000000000 + CBitFieldMaskBit51 = 0x8000000000000 + CBitFieldMaskBit52 = 0x10000000000000 + CBitFieldMaskBit53 = 0x20000000000000 + CBitFieldMaskBit54 = 0x40000000000000 + CBitFieldMaskBit55 = 0x80000000000000 + CBitFieldMaskBit56 = 0x100000000000000 + CBitFieldMaskBit57 = 0x200000000000000 + CBitFieldMaskBit58 = 0x400000000000000 + CBitFieldMaskBit59 = 0x800000000000000 + CBitFieldMaskBit60 = 0x1000000000000000 + CBitFieldMaskBit61 = 0x2000000000000000 + CBitFieldMaskBit62 = 0x4000000000000000 + CBitFieldMaskBit63 = 0x8000000000000000 +) + +type SockaddrStorage struct { + Family uint16 + _ [118]uint8 + _ uint64 +} + +type TCPMD5Sig struct { + Addr SockaddrStorage + Flags uint8 + Prefixlen uint8 + Keylen uint16 + _ uint32 + Key [80]uint8 +} + +type HDDriveCmdHdr struct { + Command uint8 + Number uint8 + Feature uint8 + Count uint8 +} + +type HDGeometry struct { + Heads uint8 + Sectors uint8 + Cylinders uint16 + _ [4]byte + Start uint64 +} + +type HDDriveID struct { + Config uint16 + Cyls uint16 + Reserved2 uint16 + Heads uint16 + Track_bytes uint16 + Sector_bytes uint16 + Sectors uint16 + Vendor0 uint16 + Vendor1 uint16 + Vendor2 uint16 + Serial_no [20]uint8 + Buf_type uint16 + Buf_size uint16 + Ecc_bytes uint16 + Fw_rev [8]uint8 + Model [40]uint8 + Max_multsect uint8 + Vendor3 uint8 + Dword_io uint16 + Vendor4 uint8 + Capability uint8 + Reserved50 uint16 + Vendor5 uint8 + TPIO uint8 + Vendor6 uint8 + TDMA uint8 + Field_valid uint16 + Cur_cyls uint16 + Cur_heads uint16 + Cur_sectors uint16 + Cur_capacity0 uint16 + Cur_capacity1 uint16 + Multsect uint8 + Multsect_valid uint8 + Lba_capacity uint32 + Dma_1word uint16 + Dma_mword uint16 + Eide_pio_modes uint16 + Eide_dma_min uint16 + Eide_dma_time uint16 + Eide_pio uint16 + Eide_pio_iordy uint16 + Words69_70 [2]uint16 + Words71_74 [4]uint16 + Queue_depth uint16 + Words76_79 [4]uint16 + Major_rev_num uint16 + Minor_rev_num uint16 + Command_set_1 uint16 + Command_set_2 uint16 + Cfsse uint16 + Cfs_enable_1 uint16 + Cfs_enable_2 uint16 + Csf_default uint16 + Dma_ultra uint16 + Trseuc uint16 + TrsEuc uint16 + CurAPMvalues uint16 + Mprc uint16 + Hw_config uint16 + Acoustic uint16 + Msrqs uint16 + Sxfert uint16 + Sal uint16 + Spg uint32 + Lba_capacity_2 uint64 + Words104_125 [22]uint16 + Last_lun uint16 + Word127 uint16 + Dlf uint16 + Csfo uint16 + Words130_155 [26]uint16 + Word156 uint16 + Words157_159 [3]uint16 + Cfa_power uint16 + Words161_175 [15]uint16 + Words176_205 [30]uint16 + Words206_254 [49]uint16 + Integrity_word uint16 +} + +type Statfs_t struct { + Type int64 + Bsize int64 + Blocks uint64 + Bfree uint64 + Bavail uint64 + Files uint64 + Ffree uint64 + Fsid Fsid + Namelen int64 + Frsize int64 + Flags int64 + Spare [4]int64 +} + +const ( + ST_MANDLOCK = 0x40 + ST_NOATIME = 0x400 + ST_NODEV = 0x4 + ST_NODIRATIME = 0x800 + ST_NOEXEC = 0x8 + ST_NOSUID = 0x2 + ST_RDONLY = 0x1 + ST_RELATIME = 0x1000 + ST_SYNCHRONOUS = 0x10 +) + +type TpacketHdr struct { + Status uint64 + Len uint32 + Snaplen uint32 + Mac uint16 + Net uint16 + Sec uint32 + Usec uint32 + _ [4]byte +} + +type Tpacket2Hdr struct { + Status uint32 + Len uint32 + Snaplen uint32 + Mac uint16 + Net uint16 + Sec uint32 + Nsec uint32 + Vlan_tci uint16 + Vlan_tpid uint16 + _ [4]uint8 +} + +type Tpacket3Hdr struct { + Next_offset uint32 + Sec uint32 + Nsec uint32 + Snaplen uint32 + Len uint32 + Status uint32 + Mac uint16 + Net uint16 + Hv1 TpacketHdrVariant1 + _ [8]uint8 +} + +type TpacketHdrVariant1 struct { + Rxhash uint32 + Vlan_tci uint32 + Vlan_tpid uint16 + _ uint16 +} + +type TpacketBlockDesc struct { + Version uint32 + To_priv uint32 + Hdr [40]byte +} + +type TpacketReq struct { + Block_size uint32 + Block_nr uint32 + Frame_size uint32 + Frame_nr uint32 +} + +type TpacketReq3 struct { + Block_size uint32 + Block_nr uint32 + Frame_size uint32 + Frame_nr uint32 + Retire_blk_tov uint32 + Sizeof_priv uint32 + Feature_req_word uint32 +} + +type TpacketStats struct { + Packets uint32 + Drops uint32 +} + +type TpacketStatsV3 struct { + Packets uint32 + Drops uint32 + Freeze_q_cnt uint32 +} + +type TpacketAuxdata struct { + Status uint32 + Len uint32 + Snaplen uint32 + Mac uint16 + Net uint16 + Vlan_tci uint16 + Vlan_tpid uint16 +} + +const ( + TPACKET_V1 = 0x0 + TPACKET_V2 = 0x1 + TPACKET_V3 = 0x2 +) + +const ( + SizeofTpacketHdr = 0x20 + SizeofTpacket2Hdr = 0x20 + SizeofTpacket3Hdr = 0x30 +) + +const ( + NF_INET_PRE_ROUTING = 0x0 + NF_INET_LOCAL_IN = 0x1 + NF_INET_FORWARD = 0x2 + NF_INET_LOCAL_OUT = 0x3 + NF_INET_POST_ROUTING = 0x4 + NF_INET_NUMHOOKS = 0x5 +) + +const ( + NF_NETDEV_INGRESS = 0x0 + NF_NETDEV_NUMHOOKS = 0x1 +) + +const ( + NFPROTO_UNSPEC = 0x0 + NFPROTO_INET = 0x1 + NFPROTO_IPV4 = 0x2 + NFPROTO_ARP = 0x3 + NFPROTO_NETDEV = 0x5 + NFPROTO_BRIDGE = 0x7 + NFPROTO_IPV6 = 0xa + NFPROTO_DECNET = 0xc + NFPROTO_NUMPROTO = 0xd +) + +type Nfgenmsg struct { + Nfgen_family uint8 + Version uint8 + Res_id uint16 +} + +const ( + NFNL_BATCH_UNSPEC = 0x0 + NFNL_BATCH_GENID = 0x1 +) + +const ( + NFT_REG_VERDICT = 0x0 + NFT_REG_1 = 0x1 + NFT_REG_2 = 0x2 + NFT_REG_3 = 0x3 + NFT_REG_4 = 0x4 + NFT_REG32_00 = 0x8 + NFT_REG32_01 = 0x9 + NFT_REG32_02 = 0xa + NFT_REG32_03 = 0xb + NFT_REG32_04 = 0xc + NFT_REG32_05 = 0xd + NFT_REG32_06 = 0xe + NFT_REG32_07 = 0xf + NFT_REG32_08 = 0x10 + NFT_REG32_09 = 0x11 + NFT_REG32_10 = 0x12 + NFT_REG32_11 = 0x13 + NFT_REG32_12 = 0x14 + NFT_REG32_13 = 0x15 + NFT_REG32_14 = 0x16 + NFT_REG32_15 = 0x17 + NFT_CONTINUE = -0x1 + NFT_BREAK = -0x2 + NFT_JUMP = -0x3 + NFT_GOTO = -0x4 + NFT_RETURN = -0x5 + NFT_MSG_NEWTABLE = 0x0 + NFT_MSG_GETTABLE = 0x1 + NFT_MSG_DELTABLE = 0x2 + NFT_MSG_NEWCHAIN = 0x3 + NFT_MSG_GETCHAIN = 0x4 + NFT_MSG_DELCHAIN = 0x5 + NFT_MSG_NEWRULE = 0x6 + NFT_MSG_GETRULE = 0x7 + NFT_MSG_DELRULE = 0x8 + NFT_MSG_NEWSET = 0x9 + NFT_MSG_GETSET = 0xa + NFT_MSG_DELSET = 0xb + NFT_MSG_NEWSETELEM = 0xc + NFT_MSG_GETSETELEM = 0xd + NFT_MSG_DELSETELEM = 0xe + NFT_MSG_NEWGEN = 0xf + NFT_MSG_GETGEN = 0x10 + NFT_MSG_TRACE = 0x11 + NFT_MSG_NEWOBJ = 0x12 + NFT_MSG_GETOBJ = 0x13 + NFT_MSG_DELOBJ = 0x14 + NFT_MSG_GETOBJ_RESET = 0x15 + NFT_MSG_MAX = 0x19 + NFTA_LIST_UNPEC = 0x0 + NFTA_LIST_ELEM = 0x1 + NFTA_HOOK_UNSPEC = 0x0 + NFTA_HOOK_HOOKNUM = 0x1 + NFTA_HOOK_PRIORITY = 0x2 + NFTA_HOOK_DEV = 0x3 + NFT_TABLE_F_DORMANT = 0x1 + NFTA_TABLE_UNSPEC = 0x0 + NFTA_TABLE_NAME = 0x1 + NFTA_TABLE_FLAGS = 0x2 + NFTA_TABLE_USE = 0x3 + NFTA_CHAIN_UNSPEC = 0x0 + NFTA_CHAIN_TABLE = 0x1 + NFTA_CHAIN_HANDLE = 0x2 + NFTA_CHAIN_NAME = 0x3 + NFTA_CHAIN_HOOK = 0x4 + NFTA_CHAIN_POLICY = 0x5 + NFTA_CHAIN_USE = 0x6 + NFTA_CHAIN_TYPE = 0x7 + NFTA_CHAIN_COUNTERS = 0x8 + NFTA_CHAIN_PAD = 0x9 + NFTA_RULE_UNSPEC = 0x0 + NFTA_RULE_TABLE = 0x1 + NFTA_RULE_CHAIN = 0x2 + NFTA_RULE_HANDLE = 0x3 + NFTA_RULE_EXPRESSIONS = 0x4 + NFTA_RULE_COMPAT = 0x5 + NFTA_RULE_POSITION = 0x6 + NFTA_RULE_USERDATA = 0x7 + NFTA_RULE_PAD = 0x8 + NFTA_RULE_ID = 0x9 + NFT_RULE_COMPAT_F_INV = 0x2 + NFT_RULE_COMPAT_F_MASK = 0x2 + NFTA_RULE_COMPAT_UNSPEC = 0x0 + NFTA_RULE_COMPAT_PROTO = 0x1 + NFTA_RULE_COMPAT_FLAGS = 0x2 + NFT_SET_ANONYMOUS = 0x1 + NFT_SET_CONSTANT = 0x2 + NFT_SET_INTERVAL = 0x4 + NFT_SET_MAP = 0x8 + NFT_SET_TIMEOUT = 0x10 + NFT_SET_EVAL = 0x20 + NFT_SET_OBJECT = 0x40 + NFT_SET_POL_PERFORMANCE = 0x0 + NFT_SET_POL_MEMORY = 0x1 + NFTA_SET_DESC_UNSPEC = 0x0 + NFTA_SET_DESC_SIZE = 0x1 + NFTA_SET_UNSPEC = 0x0 + NFTA_SET_TABLE = 0x1 + NFTA_SET_NAME = 0x2 + NFTA_SET_FLAGS = 0x3 + NFTA_SET_KEY_TYPE = 0x4 + NFTA_SET_KEY_LEN = 0x5 + NFTA_SET_DATA_TYPE = 0x6 + NFTA_SET_DATA_LEN = 0x7 + NFTA_SET_POLICY = 0x8 + NFTA_SET_DESC = 0x9 + NFTA_SET_ID = 0xa + NFTA_SET_TIMEOUT = 0xb + NFTA_SET_GC_INTERVAL = 0xc + NFTA_SET_USERDATA = 0xd + NFTA_SET_PAD = 0xe + NFTA_SET_OBJ_TYPE = 0xf + NFT_SET_ELEM_INTERVAL_END = 0x1 + NFTA_SET_ELEM_UNSPEC = 0x0 + NFTA_SET_ELEM_KEY = 0x1 + NFTA_SET_ELEM_DATA = 0x2 + NFTA_SET_ELEM_FLAGS = 0x3 + NFTA_SET_ELEM_TIMEOUT = 0x4 + NFTA_SET_ELEM_EXPIRATION = 0x5 + NFTA_SET_ELEM_USERDATA = 0x6 + NFTA_SET_ELEM_EXPR = 0x7 + NFTA_SET_ELEM_PAD = 0x8 + NFTA_SET_ELEM_OBJREF = 0x9 + NFTA_SET_ELEM_LIST_UNSPEC = 0x0 + NFTA_SET_ELEM_LIST_TABLE = 0x1 + NFTA_SET_ELEM_LIST_SET = 0x2 + NFTA_SET_ELEM_LIST_ELEMENTS = 0x3 + NFTA_SET_ELEM_LIST_SET_ID = 0x4 + NFT_DATA_VALUE = 0x0 + NFT_DATA_VERDICT = 0xffffff00 + NFTA_DATA_UNSPEC = 0x0 + NFTA_DATA_VALUE = 0x1 + NFTA_DATA_VERDICT = 0x2 + NFTA_VERDICT_UNSPEC = 0x0 + NFTA_VERDICT_CODE = 0x1 + NFTA_VERDICT_CHAIN = 0x2 + NFTA_EXPR_UNSPEC = 0x0 + NFTA_EXPR_NAME = 0x1 + NFTA_EXPR_DATA = 0x2 + NFTA_IMMEDIATE_UNSPEC = 0x0 + NFTA_IMMEDIATE_DREG = 0x1 + NFTA_IMMEDIATE_DATA = 0x2 + NFTA_BITWISE_UNSPEC = 0x0 + NFTA_BITWISE_SREG = 0x1 + NFTA_BITWISE_DREG = 0x2 + NFTA_BITWISE_LEN = 0x3 + NFTA_BITWISE_MASK = 0x4 + NFTA_BITWISE_XOR = 0x5 + NFT_BYTEORDER_NTOH = 0x0 + NFT_BYTEORDER_HTON = 0x1 + NFTA_BYTEORDER_UNSPEC = 0x0 + NFTA_BYTEORDER_SREG = 0x1 + NFTA_BYTEORDER_DREG = 0x2 + NFTA_BYTEORDER_OP = 0x3 + NFTA_BYTEORDER_LEN = 0x4 + NFTA_BYTEORDER_SIZE = 0x5 + NFT_CMP_EQ = 0x0 + NFT_CMP_NEQ = 0x1 + NFT_CMP_LT = 0x2 + NFT_CMP_LTE = 0x3 + NFT_CMP_GT = 0x4 + NFT_CMP_GTE = 0x5 + NFTA_CMP_UNSPEC = 0x0 + NFTA_CMP_SREG = 0x1 + NFTA_CMP_OP = 0x2 + NFTA_CMP_DATA = 0x3 + NFT_RANGE_EQ = 0x0 + NFT_RANGE_NEQ = 0x1 + NFTA_RANGE_UNSPEC = 0x0 + NFTA_RANGE_SREG = 0x1 + NFTA_RANGE_OP = 0x2 + NFTA_RANGE_FROM_DATA = 0x3 + NFTA_RANGE_TO_DATA = 0x4 + NFT_LOOKUP_F_INV = 0x1 + NFTA_LOOKUP_UNSPEC = 0x0 + NFTA_LOOKUP_SET = 0x1 + NFTA_LOOKUP_SREG = 0x2 + NFTA_LOOKUP_DREG = 0x3 + NFTA_LOOKUP_SET_ID = 0x4 + NFTA_LOOKUP_FLAGS = 0x5 + NFT_DYNSET_OP_ADD = 0x0 + NFT_DYNSET_OP_UPDATE = 0x1 + NFT_DYNSET_F_INV = 0x1 + NFTA_DYNSET_UNSPEC = 0x0 + NFTA_DYNSET_SET_NAME = 0x1 + NFTA_DYNSET_SET_ID = 0x2 + NFTA_DYNSET_OP = 0x3 + NFTA_DYNSET_SREG_KEY = 0x4 + NFTA_DYNSET_SREG_DATA = 0x5 + NFTA_DYNSET_TIMEOUT = 0x6 + NFTA_DYNSET_EXPR = 0x7 + NFTA_DYNSET_PAD = 0x8 + NFTA_DYNSET_FLAGS = 0x9 + NFT_PAYLOAD_LL_HEADER = 0x0 + NFT_PAYLOAD_NETWORK_HEADER = 0x1 + NFT_PAYLOAD_TRANSPORT_HEADER = 0x2 + NFT_PAYLOAD_CSUM_NONE = 0x0 + NFT_PAYLOAD_CSUM_INET = 0x1 + NFT_PAYLOAD_L4CSUM_PSEUDOHDR = 0x1 + NFTA_PAYLOAD_UNSPEC = 0x0 + NFTA_PAYLOAD_DREG = 0x1 + NFTA_PAYLOAD_BASE = 0x2 + NFTA_PAYLOAD_OFFSET = 0x3 + NFTA_PAYLOAD_LEN = 0x4 + NFTA_PAYLOAD_SREG = 0x5 + NFTA_PAYLOAD_CSUM_TYPE = 0x6 + NFTA_PAYLOAD_CSUM_OFFSET = 0x7 + NFTA_PAYLOAD_CSUM_FLAGS = 0x8 + NFT_EXTHDR_F_PRESENT = 0x1 + NFT_EXTHDR_OP_IPV6 = 0x0 + NFT_EXTHDR_OP_TCPOPT = 0x1 + NFTA_EXTHDR_UNSPEC = 0x0 + NFTA_EXTHDR_DREG = 0x1 + NFTA_EXTHDR_TYPE = 0x2 + NFTA_EXTHDR_OFFSET = 0x3 + NFTA_EXTHDR_LEN = 0x4 + NFTA_EXTHDR_FLAGS = 0x5 + NFTA_EXTHDR_OP = 0x6 + NFTA_EXTHDR_SREG = 0x7 + NFT_META_LEN = 0x0 + NFT_META_PROTOCOL = 0x1 + NFT_META_PRIORITY = 0x2 + NFT_META_MARK = 0x3 + NFT_META_IIF = 0x4 + NFT_META_OIF = 0x5 + NFT_META_IIFNAME = 0x6 + NFT_META_OIFNAME = 0x7 + NFT_META_IIFTYPE = 0x8 + NFT_META_OIFTYPE = 0x9 + NFT_META_SKUID = 0xa + NFT_META_SKGID = 0xb + NFT_META_NFTRACE = 0xc + NFT_META_RTCLASSID = 0xd + NFT_META_SECMARK = 0xe + NFT_META_NFPROTO = 0xf + NFT_META_L4PROTO = 0x10 + NFT_META_BRI_IIFNAME = 0x11 + NFT_META_BRI_OIFNAME = 0x12 + NFT_META_PKTTYPE = 0x13 + NFT_META_CPU = 0x14 + NFT_META_IIFGROUP = 0x15 + NFT_META_OIFGROUP = 0x16 + NFT_META_CGROUP = 0x17 + NFT_META_PRANDOM = 0x18 + NFT_RT_CLASSID = 0x0 + NFT_RT_NEXTHOP4 = 0x1 + NFT_RT_NEXTHOP6 = 0x2 + NFT_RT_TCPMSS = 0x3 + NFT_HASH_JENKINS = 0x0 + NFT_HASH_SYM = 0x1 + NFTA_HASH_UNSPEC = 0x0 + NFTA_HASH_SREG = 0x1 + NFTA_HASH_DREG = 0x2 + NFTA_HASH_LEN = 0x3 + NFTA_HASH_MODULUS = 0x4 + NFTA_HASH_SEED = 0x5 + NFTA_HASH_OFFSET = 0x6 + NFTA_HASH_TYPE = 0x7 + NFTA_META_UNSPEC = 0x0 + NFTA_META_DREG = 0x1 + NFTA_META_KEY = 0x2 + NFTA_META_SREG = 0x3 + NFTA_RT_UNSPEC = 0x0 + NFTA_RT_DREG = 0x1 + NFTA_RT_KEY = 0x2 + NFT_CT_STATE = 0x0 + NFT_CT_DIRECTION = 0x1 + NFT_CT_STATUS = 0x2 + NFT_CT_MARK = 0x3 + NFT_CT_SECMARK = 0x4 + NFT_CT_EXPIRATION = 0x5 + NFT_CT_HELPER = 0x6 + NFT_CT_L3PROTOCOL = 0x7 + NFT_CT_SRC = 0x8 + NFT_CT_DST = 0x9 + NFT_CT_PROTOCOL = 0xa + NFT_CT_PROTO_SRC = 0xb + NFT_CT_PROTO_DST = 0xc + NFT_CT_LABELS = 0xd + NFT_CT_PKTS = 0xe + NFT_CT_BYTES = 0xf + NFT_CT_AVGPKT = 0x10 + NFT_CT_ZONE = 0x11 + NFT_CT_EVENTMASK = 0x12 + NFTA_CT_UNSPEC = 0x0 + NFTA_CT_DREG = 0x1 + NFTA_CT_KEY = 0x2 + NFTA_CT_DIRECTION = 0x3 + NFTA_CT_SREG = 0x4 + NFT_LIMIT_PKTS = 0x0 + NFT_LIMIT_PKT_BYTES = 0x1 + NFT_LIMIT_F_INV = 0x1 + NFTA_LIMIT_UNSPEC = 0x0 + NFTA_LIMIT_RATE = 0x1 + NFTA_LIMIT_UNIT = 0x2 + NFTA_LIMIT_BURST = 0x3 + NFTA_LIMIT_TYPE = 0x4 + NFTA_LIMIT_FLAGS = 0x5 + NFTA_LIMIT_PAD = 0x6 + NFTA_COUNTER_UNSPEC = 0x0 + NFTA_COUNTER_BYTES = 0x1 + NFTA_COUNTER_PACKETS = 0x2 + NFTA_COUNTER_PAD = 0x3 + NFTA_LOG_UNSPEC = 0x0 + NFTA_LOG_GROUP = 0x1 + NFTA_LOG_PREFIX = 0x2 + NFTA_LOG_SNAPLEN = 0x3 + NFTA_LOG_QTHRESHOLD = 0x4 + NFTA_LOG_LEVEL = 0x5 + NFTA_LOG_FLAGS = 0x6 + NFTA_QUEUE_UNSPEC = 0x0 + NFTA_QUEUE_NUM = 0x1 + NFTA_QUEUE_TOTAL = 0x2 + NFTA_QUEUE_FLAGS = 0x3 + NFTA_QUEUE_SREG_QNUM = 0x4 + NFT_QUOTA_F_INV = 0x1 + NFT_QUOTA_F_DEPLETED = 0x2 + NFTA_QUOTA_UNSPEC = 0x0 + NFTA_QUOTA_BYTES = 0x1 + NFTA_QUOTA_FLAGS = 0x2 + NFTA_QUOTA_PAD = 0x3 + NFTA_QUOTA_CONSUMED = 0x4 + NFT_REJECT_ICMP_UNREACH = 0x0 + NFT_REJECT_TCP_RST = 0x1 + NFT_REJECT_ICMPX_UNREACH = 0x2 + NFT_REJECT_ICMPX_NO_ROUTE = 0x0 + NFT_REJECT_ICMPX_PORT_UNREACH = 0x1 + NFT_REJECT_ICMPX_HOST_UNREACH = 0x2 + NFT_REJECT_ICMPX_ADMIN_PROHIBITED = 0x3 + NFTA_REJECT_UNSPEC = 0x0 + NFTA_REJECT_TYPE = 0x1 + NFTA_REJECT_ICMP_CODE = 0x2 + NFT_NAT_SNAT = 0x0 + NFT_NAT_DNAT = 0x1 + NFTA_NAT_UNSPEC = 0x0 + NFTA_NAT_TYPE = 0x1 + NFTA_NAT_FAMILY = 0x2 + NFTA_NAT_REG_ADDR_MIN = 0x3 + NFTA_NAT_REG_ADDR_MAX = 0x4 + NFTA_NAT_REG_PROTO_MIN = 0x5 + NFTA_NAT_REG_PROTO_MAX = 0x6 + NFTA_NAT_FLAGS = 0x7 + NFTA_MASQ_UNSPEC = 0x0 + NFTA_MASQ_FLAGS = 0x1 + NFTA_MASQ_REG_PROTO_MIN = 0x2 + NFTA_MASQ_REG_PROTO_MAX = 0x3 + NFTA_REDIR_UNSPEC = 0x0 + NFTA_REDIR_REG_PROTO_MIN = 0x1 + NFTA_REDIR_REG_PROTO_MAX = 0x2 + NFTA_REDIR_FLAGS = 0x3 + NFTA_DUP_UNSPEC = 0x0 + NFTA_DUP_SREG_ADDR = 0x1 + NFTA_DUP_SREG_DEV = 0x2 + NFTA_FWD_UNSPEC = 0x0 + NFTA_FWD_SREG_DEV = 0x1 + NFTA_OBJREF_UNSPEC = 0x0 + NFTA_OBJREF_IMM_TYPE = 0x1 + NFTA_OBJREF_IMM_NAME = 0x2 + NFTA_OBJREF_SET_SREG = 0x3 + NFTA_OBJREF_SET_NAME = 0x4 + NFTA_OBJREF_SET_ID = 0x5 + NFTA_GEN_UNSPEC = 0x0 + NFTA_GEN_ID = 0x1 + NFTA_GEN_PROC_PID = 0x2 + NFTA_GEN_PROC_NAME = 0x3 + NFTA_FIB_UNSPEC = 0x0 + NFTA_FIB_DREG = 0x1 + NFTA_FIB_RESULT = 0x2 + NFTA_FIB_FLAGS = 0x3 + NFT_FIB_RESULT_UNSPEC = 0x0 + NFT_FIB_RESULT_OIF = 0x1 + NFT_FIB_RESULT_OIFNAME = 0x2 + NFT_FIB_RESULT_ADDRTYPE = 0x3 + NFTA_FIB_F_SADDR = 0x1 + NFTA_FIB_F_DADDR = 0x2 + NFTA_FIB_F_MARK = 0x4 + NFTA_FIB_F_IIF = 0x8 + NFTA_FIB_F_OIF = 0x10 + NFTA_FIB_F_PRESENT = 0x20 + NFTA_CT_HELPER_UNSPEC = 0x0 + NFTA_CT_HELPER_NAME = 0x1 + NFTA_CT_HELPER_L3PROTO = 0x2 + NFTA_CT_HELPER_L4PROTO = 0x3 + NFTA_OBJ_UNSPEC = 0x0 + NFTA_OBJ_TABLE = 0x1 + NFTA_OBJ_NAME = 0x2 + NFTA_OBJ_TYPE = 0x3 + NFTA_OBJ_DATA = 0x4 + NFTA_OBJ_USE = 0x5 + NFTA_TRACE_UNSPEC = 0x0 + NFTA_TRACE_TABLE = 0x1 + NFTA_TRACE_CHAIN = 0x2 + NFTA_TRACE_RULE_HANDLE = 0x3 + NFTA_TRACE_TYPE = 0x4 + NFTA_TRACE_VERDICT = 0x5 + NFTA_TRACE_ID = 0x6 + NFTA_TRACE_LL_HEADER = 0x7 + NFTA_TRACE_NETWORK_HEADER = 0x8 + NFTA_TRACE_TRANSPORT_HEADER = 0x9 + NFTA_TRACE_IIF = 0xa + NFTA_TRACE_IIFTYPE = 0xb + NFTA_TRACE_OIF = 0xc + NFTA_TRACE_OIFTYPE = 0xd + NFTA_TRACE_MARK = 0xe + NFTA_TRACE_NFPROTO = 0xf + NFTA_TRACE_POLICY = 0x10 + NFTA_TRACE_PAD = 0x11 + NFT_TRACETYPE_UNSPEC = 0x0 + NFT_TRACETYPE_POLICY = 0x1 + NFT_TRACETYPE_RETURN = 0x2 + NFT_TRACETYPE_RULE = 0x3 + NFTA_NG_UNSPEC = 0x0 + NFTA_NG_DREG = 0x1 + NFTA_NG_MODULUS = 0x2 + NFTA_NG_TYPE = 0x3 + NFTA_NG_OFFSET = 0x4 + NFT_NG_INCREMENTAL = 0x0 + NFT_NG_RANDOM = 0x1 +) + +type RTCTime struct { + Sec int32 + Min int32 + Hour int32 + Mday int32 + Mon int32 + Year int32 + Wday int32 + Yday int32 + Isdst int32 +} + +type RTCWkAlrm struct { + Enabled uint8 + Pending uint8 + _ [2]byte + Time RTCTime +} + +type RTCPLLInfo struct { + Ctrl int32 + Value int32 + Max int32 + Min int32 + Posmult int32 + Negmult int32 + Clock int64 +} + +type BlkpgIoctlArg struct { + Op int32 + Flags int32 + Datalen int32 + _ [4]byte + Data *byte +} + +type BlkpgPartition struct { + Start int64 + Length int64 + Pno int32 + Devname [64]uint8 + Volname [64]uint8 + _ [4]byte +} + +const ( + BLKPG = 0x1269 + BLKPG_ADD_PARTITION = 0x1 + BLKPG_DEL_PARTITION = 0x2 + BLKPG_RESIZE_PARTITION = 0x3 +) + +const ( + NETNSA_NONE = 0x0 + NETNSA_NSID = 0x1 + NETNSA_PID = 0x2 + NETNSA_FD = 0x3 +) diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_s390x.go b/vendor/golang.org/x/sys/unix/ztypes_linux_s390x.go index 898ac45..0c79054 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_s390x.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_s390x.go @@ -514,6 +514,13 @@ const ( RTA_FLOW = 0xb RTA_CACHEINFO = 0xc RTA_TABLE = 0xf + RTA_MARK = 0x10 + RTA_MFC_STATS = 0x11 + RTA_VIA = 0x12 + RTA_NEWDST = 0x13 + RTA_PREF = 0x14 + RTA_ENCAP_TYPE = 0x15 + RTA_ENCAP = 0x16 RTN_UNSPEC = 0x0 RTN_UNICAST = 0x1 RTN_LOCAL = 0x2 diff --git a/vendor/golang.org/x/sys/windows/syscall_windows.go b/vendor/golang.org/x/sys/windows/syscall_windows.go index fd89e08..8a00b71 100644 --- a/vendor/golang.org/x/sys/windows/syscall_windows.go +++ b/vendor/golang.org/x/sys/windows/syscall_windows.go @@ -655,7 +655,7 @@ type RawSockaddr struct { type RawSockaddrAny struct { Addr RawSockaddr - Pad [96]int8 + Pad [100]int8 } type Sockaddr interface { @@ -704,19 +704,69 @@ func (sa *SockaddrInet6) sockaddr() (unsafe.Pointer, int32, error) { return unsafe.Pointer(&sa.raw), int32(unsafe.Sizeof(sa.raw)), nil } +type RawSockaddrUnix struct { + Family uint16 + Path [UNIX_PATH_MAX]int8 +} + type SockaddrUnix struct { Name string + raw RawSockaddrUnix } func (sa *SockaddrUnix) sockaddr() (unsafe.Pointer, int32, error) { - // TODO(brainman): implement SockaddrUnix.sockaddr() - return nil, 0, syscall.EWINDOWS + name := sa.Name + n := len(name) + if n > len(sa.raw.Path) { + return nil, 0, syscall.EINVAL + } + if n == len(sa.raw.Path) && name[0] != '@' { + return nil, 0, syscall.EINVAL + } + sa.raw.Family = AF_UNIX + for i := 0; i < n; i++ { + sa.raw.Path[i] = int8(name[i]) + } + // length is family (uint16), name, NUL. + sl := int32(2) + if n > 0 { + sl += int32(n) + 1 + } + if sa.raw.Path[0] == '@' { + sa.raw.Path[0] = 0 + // Don't count trailing NUL for abstract address. + sl-- + } + + return unsafe.Pointer(&sa.raw), sl, nil } func (rsa *RawSockaddrAny) Sockaddr() (Sockaddr, error) { switch rsa.Addr.Family { case AF_UNIX: - return nil, syscall.EWINDOWS + pp := (*RawSockaddrUnix)(unsafe.Pointer(rsa)) + sa := new(SockaddrUnix) + if pp.Path[0] == 0 { + // "Abstract" Unix domain socket. + // Rewrite leading NUL as @ for textual display. + // (This is the standard convention.) + // Not friendly to overwrite in place, + // but the callers below don't care. + pp.Path[0] = '@' + } + + // Assume path ends at NUL. + // This is not technically the Linux semantics for + // abstract Unix domain sockets--they are supposed + // to be uninterpreted fixed-size binary blobs--but + // everyone uses this convention. + n := 0 + for n < len(pp.Path) && pp.Path[n] != 0 { + n++ + } + bytes := (*[10000]byte)(unsafe.Pointer(&pp.Path[0]))[0:n] + sa.Name = string(bytes) + return sa, nil case AF_INET: pp := (*RawSockaddrInet4)(unsafe.Pointer(rsa)) diff --git a/vendor/golang.org/x/sys/windows/types_windows.go b/vendor/golang.org/x/sys/windows/types_windows.go index 7f8b3af..141ca81 100644 --- a/vendor/golang.org/x/sys/windows/types_windows.go +++ b/vendor/golang.org/x/sys/windows/types_windows.go @@ -1453,7 +1453,7 @@ type SmallRect struct { Bottom int16 } -// Used with GetConsoleScreenBuffer to retreive information about a console +// Used with GetConsoleScreenBuffer to retrieve information about a console // screen buffer. See // https://docs.microsoft.com/en-us/windows/console/console-screen-buffer-info-str // for details. @@ -1465,3 +1465,5 @@ type ConsoleScreenBufferInfo struct { Window SmallRect MaximumWindowSize Coord } + +const UNIX_PATH_MAX = 108 // defined in afunix.h