mirror of
https://github.com/go-vgo/robotgo.git
synced 2025-06-01 14:43:55 +00:00
update vendor pkg to newest
This commit is contained in:
parent
75b468839f
commit
3d65e37f98
10
Gopkg.lock
generated
10
Gopkg.lock
generated
@ -50,6 +50,12 @@
|
|||||||
revision = "b026a6fd291f00736db60738f4e83a79d26359cb"
|
revision = "b026a6fd291f00736db60738f4e83a79d26359cb"
|
||||||
version = "v2.2.0"
|
version = "v2.2.0"
|
||||||
|
|
||||||
|
[[projects]]
|
||||||
|
branch = "master"
|
||||||
|
name = "github.com/robotn/gohook"
|
||||||
|
packages = ["."]
|
||||||
|
revision = "3dccbf0083168096c576bf62abb3d5d4c916e2ea"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
name = "github.com/shirou/gopsutil"
|
name = "github.com/shirou/gopsutil"
|
||||||
packages = [
|
packages = [
|
||||||
@ -88,11 +94,11 @@
|
|||||||
"unix",
|
"unix",
|
||||||
"windows"
|
"windows"
|
||||||
]
|
]
|
||||||
revision = "49385e6e15226593f68b26af201feec29d5bba22"
|
revision = "d0be0721c37eeb5299f245a996a483160fc36940"
|
||||||
|
|
||||||
[solve-meta]
|
[solve-meta]
|
||||||
analyzer-name = "dep"
|
analyzer-name = "dep"
|
||||||
analyzer-version = 1
|
analyzer-version = 1
|
||||||
inputs-digest = "0fd06dbf29cbad04968ef5a7c12e61c18ab8595bcb2d30c9f35698f0873916d1"
|
inputs-digest = "b1299bcf48c5b674a219acd0d53d6e1dc9cd44f60a9448f74d2fb623eaf9b00a"
|
||||||
solver-name = "gps-cdcl"
|
solver-name = "gps-cdcl"
|
||||||
solver-version = 1
|
solver-version = 1
|
||||||
|
@ -1 +1 @@
|
|||||||
C language dependent package, better to compilation. You need to follow the relevant agreement and LICENSE.
|
C language dependent package, better to compilation.
|
24
vendor/github.com/robotn/gohook/.gitignore
generated
vendored
Normal file
24
vendor/github.com/robotn/gohook/.gitignore
generated
vendored
Normal file
@ -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
|
674
vendor/github.com/robotn/gohook/LICENSE
generated
vendored
Normal file
674
vendor/github.com/robotn/gohook/LICENSE
generated
vendored
Normal file
@ -0,0 +1,674 @@
|
|||||||
|
GNU GENERAL PUBLIC LICENSE
|
||||||
|
Version 3, 29 June 2007
|
||||||
|
|
||||||
|
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||||
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
|
of this license document, but changing it is not allowed.
|
||||||
|
|
||||||
|
Preamble
|
||||||
|
|
||||||
|
The GNU General Public License is a free, copyleft license for
|
||||||
|
software and other kinds of works.
|
||||||
|
|
||||||
|
The licenses for most software and other practical works are designed
|
||||||
|
to take away your freedom to share and change the works. By contrast,
|
||||||
|
the GNU General Public License is intended to guarantee your freedom to
|
||||||
|
share and change all versions of a program--to make sure it remains free
|
||||||
|
software for all its users. We, the Free Software Foundation, use the
|
||||||
|
GNU General Public License for most of our software; it applies also to
|
||||||
|
any other work released this way by its authors. You can apply it to
|
||||||
|
your programs, too.
|
||||||
|
|
||||||
|
When we speak of free software, we are referring to freedom, not
|
||||||
|
price. Our General Public Licenses are designed to make sure that you
|
||||||
|
have the freedom to distribute copies of free software (and charge for
|
||||||
|
them if you wish), that you receive source code or can get it if you
|
||||||
|
want it, that you can change the software or use pieces of it in new
|
||||||
|
free programs, and that you know you can do these things.
|
||||||
|
|
||||||
|
To protect your rights, we need to prevent others from denying you
|
||||||
|
these rights or asking you to surrender the rights. Therefore, you have
|
||||||
|
certain responsibilities if you distribute copies of the software, or if
|
||||||
|
you modify it: responsibilities to respect the freedom of others.
|
||||||
|
|
||||||
|
For example, if you distribute copies of such a program, whether
|
||||||
|
gratis or for a fee, you must pass on to the recipients the same
|
||||||
|
freedoms that you received. You must make sure that they, too, receive
|
||||||
|
or can get the source code. And you must show them these terms so they
|
||||||
|
know their rights.
|
||||||
|
|
||||||
|
Developers that use the GNU GPL protect your rights with two steps:
|
||||||
|
(1) assert copyright on the software, and (2) offer you this License
|
||||||
|
giving you legal permission to copy, distribute and/or modify it.
|
||||||
|
|
||||||
|
For the developers' and authors' protection, the GPL clearly explains
|
||||||
|
that there is no warranty for this free software. For both users' and
|
||||||
|
authors' sake, the GPL requires that modified versions be marked as
|
||||||
|
changed, so that their problems will not be attributed erroneously to
|
||||||
|
authors of previous versions.
|
||||||
|
|
||||||
|
Some devices are designed to deny users access to install or run
|
||||||
|
modified versions of the software inside them, although the manufacturer
|
||||||
|
can do so. This is fundamentally incompatible with the aim of
|
||||||
|
protecting users' freedom to change the software. The systematic
|
||||||
|
pattern of such abuse occurs in the area of products for individuals to
|
||||||
|
use, which is precisely where it is most unacceptable. Therefore, we
|
||||||
|
have designed this version of the GPL to prohibit the practice for those
|
||||||
|
products. If such problems arise substantially in other domains, we
|
||||||
|
stand ready to extend this provision to those domains in future versions
|
||||||
|
of the GPL, as needed to protect the freedom of users.
|
||||||
|
|
||||||
|
Finally, every program is threatened constantly by software patents.
|
||||||
|
States should not allow patents to restrict development and use of
|
||||||
|
software on general-purpose computers, but in those that do, we wish to
|
||||||
|
avoid the special danger that patents applied to a free program could
|
||||||
|
make it effectively proprietary. To prevent this, the GPL assures that
|
||||||
|
patents cannot be used to render the program non-free.
|
||||||
|
|
||||||
|
The precise terms and conditions for copying, distribution and
|
||||||
|
modification follow.
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
0. Definitions.
|
||||||
|
|
||||||
|
"This License" refers to version 3 of the GNU General Public License.
|
||||||
|
|
||||||
|
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||||
|
works, such as semiconductor masks.
|
||||||
|
|
||||||
|
"The Program" refers to any copyrightable work licensed under this
|
||||||
|
License. Each licensee is addressed as "you". "Licensees" and
|
||||||
|
"recipients" may be individuals or organizations.
|
||||||
|
|
||||||
|
To "modify" a work means to copy from or adapt all or part of the work
|
||||||
|
in a fashion requiring copyright permission, other than the making of an
|
||||||
|
exact copy. The resulting work is called a "modified version" of the
|
||||||
|
earlier work or a work "based on" the earlier work.
|
||||||
|
|
||||||
|
A "covered work" means either the unmodified Program or a work based
|
||||||
|
on the Program.
|
||||||
|
|
||||||
|
To "propagate" a work means to do anything with it that, without
|
||||||
|
permission, would make you directly or secondarily liable for
|
||||||
|
infringement under applicable copyright law, except executing it on a
|
||||||
|
computer or modifying a private copy. Propagation includes copying,
|
||||||
|
distribution (with or without modification), making available to the
|
||||||
|
public, and in some countries other activities as well.
|
||||||
|
|
||||||
|
To "convey" a work means any kind of propagation that enables other
|
||||||
|
parties to make or receive copies. Mere interaction with a user through
|
||||||
|
a computer network, with no transfer of a copy, is not conveying.
|
||||||
|
|
||||||
|
An interactive user interface displays "Appropriate Legal Notices"
|
||||||
|
to the extent that it includes a convenient and prominently visible
|
||||||
|
feature that (1) displays an appropriate copyright notice, and (2)
|
||||||
|
tells the user that there is no warranty for the work (except to the
|
||||||
|
extent that warranties are provided), that licensees may convey the
|
||||||
|
work under this License, and how to view a copy of this License. If
|
||||||
|
the interface presents a list of user commands or options, such as a
|
||||||
|
menu, a prominent item in the list meets this criterion.
|
||||||
|
|
||||||
|
1. Source Code.
|
||||||
|
|
||||||
|
The "source code" for a work means the preferred form of the work
|
||||||
|
for making modifications to it. "Object code" means any non-source
|
||||||
|
form of a work.
|
||||||
|
|
||||||
|
A "Standard Interface" means an interface that either is an official
|
||||||
|
standard defined by a recognized standards body, or, in the case of
|
||||||
|
interfaces specified for a particular programming language, one that
|
||||||
|
is widely used among developers working in that language.
|
||||||
|
|
||||||
|
The "System Libraries" of an executable work include anything, other
|
||||||
|
than the work as a whole, that (a) is included in the normal form of
|
||||||
|
packaging a Major Component, but which is not part of that Major
|
||||||
|
Component, and (b) serves only to enable use of the work with that
|
||||||
|
Major Component, or to implement a Standard Interface for which an
|
||||||
|
implementation is available to the public in source code form. A
|
||||||
|
"Major Component", in this context, means a major essential component
|
||||||
|
(kernel, window system, and so on) of the specific operating system
|
||||||
|
(if any) on which the executable work runs, or a compiler used to
|
||||||
|
produce the work, or an object code interpreter used to run it.
|
||||||
|
|
||||||
|
The "Corresponding Source" for a work in object code form means all
|
||||||
|
the source code needed to generate, install, and (for an executable
|
||||||
|
work) run the object code and to modify the work, including scripts to
|
||||||
|
control those activities. However, it does not include the work's
|
||||||
|
System Libraries, or general-purpose tools or generally available free
|
||||||
|
programs which are used unmodified in performing those activities but
|
||||||
|
which are not part of the work. For example, Corresponding Source
|
||||||
|
includes interface definition files associated with source files for
|
||||||
|
the work, and the source code for shared libraries and dynamically
|
||||||
|
linked subprograms that the work is specifically designed to require,
|
||||||
|
such as by intimate data communication or control flow between those
|
||||||
|
subprograms and other parts of the work.
|
||||||
|
|
||||||
|
The Corresponding Source need not include anything that users
|
||||||
|
can regenerate automatically from other parts of the Corresponding
|
||||||
|
Source.
|
||||||
|
|
||||||
|
The Corresponding Source for a work in source code form is that
|
||||||
|
same work.
|
||||||
|
|
||||||
|
2. Basic Permissions.
|
||||||
|
|
||||||
|
All rights granted under this License are granted for the term of
|
||||||
|
copyright on the Program, and are irrevocable provided the stated
|
||||||
|
conditions are met. This License explicitly affirms your unlimited
|
||||||
|
permission to run the unmodified Program. The output from running a
|
||||||
|
covered work is covered by this License only if the output, given its
|
||||||
|
content, constitutes a covered work. This License acknowledges your
|
||||||
|
rights of fair use or other equivalent, as provided by copyright law.
|
||||||
|
|
||||||
|
You may make, run and propagate covered works that you do not
|
||||||
|
convey, without conditions so long as your license otherwise remains
|
||||||
|
in force. You may convey covered works to others for the sole purpose
|
||||||
|
of having them make modifications exclusively for you, or provide you
|
||||||
|
with facilities for running those works, provided that you comply with
|
||||||
|
the terms of this License in conveying all material for which you do
|
||||||
|
not control copyright. Those thus making or running the covered works
|
||||||
|
for you must do so exclusively on your behalf, under your direction
|
||||||
|
and control, on terms that prohibit them from making any copies of
|
||||||
|
your copyrighted material outside their relationship with you.
|
||||||
|
|
||||||
|
Conveying under any other circumstances is permitted solely under
|
||||||
|
the conditions stated below. Sublicensing is not allowed; section 10
|
||||||
|
makes it unnecessary.
|
||||||
|
|
||||||
|
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||||
|
|
||||||
|
No covered work shall be deemed part of an effective technological
|
||||||
|
measure under any applicable law fulfilling obligations under article
|
||||||
|
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||||
|
similar laws prohibiting or restricting circumvention of such
|
||||||
|
measures.
|
||||||
|
|
||||||
|
When you convey a covered work, you waive any legal power to forbid
|
||||||
|
circumvention of technological measures to the extent such circumvention
|
||||||
|
is effected by exercising rights under this License with respect to
|
||||||
|
the covered work, and you disclaim any intention to limit operation or
|
||||||
|
modification of the work as a means of enforcing, against the work's
|
||||||
|
users, your or third parties' legal rights to forbid circumvention of
|
||||||
|
technological measures.
|
||||||
|
|
||||||
|
4. Conveying Verbatim Copies.
|
||||||
|
|
||||||
|
You may convey verbatim copies of the Program's source code as you
|
||||||
|
receive it, in any medium, provided that you conspicuously and
|
||||||
|
appropriately publish on each copy an appropriate copyright notice;
|
||||||
|
keep intact all notices stating that this License and any
|
||||||
|
non-permissive terms added in accord with section 7 apply to the code;
|
||||||
|
keep intact all notices of the absence of any warranty; and give all
|
||||||
|
recipients a copy of this License along with the Program.
|
||||||
|
|
||||||
|
You may charge any price or no price for each copy that you convey,
|
||||||
|
and you may offer support or warranty protection for a fee.
|
||||||
|
|
||||||
|
5. Conveying Modified Source Versions.
|
||||||
|
|
||||||
|
You may convey a work based on the Program, or the modifications to
|
||||||
|
produce it from the Program, in the form of source code under the
|
||||||
|
terms of section 4, provided that you also meet all of these conditions:
|
||||||
|
|
||||||
|
a) The work must carry prominent notices stating that you modified
|
||||||
|
it, and giving a relevant date.
|
||||||
|
|
||||||
|
b) The work must carry prominent notices stating that it is
|
||||||
|
released under this License and any conditions added under section
|
||||||
|
7. This requirement modifies the requirement in section 4 to
|
||||||
|
"keep intact all notices".
|
||||||
|
|
||||||
|
c) You must license the entire work, as a whole, under this
|
||||||
|
License to anyone who comes into possession of a copy. This
|
||||||
|
License will therefore apply, along with any applicable section 7
|
||||||
|
additional terms, to the whole of the work, and all its parts,
|
||||||
|
regardless of how they are packaged. This License gives no
|
||||||
|
permission to license the work in any other way, but it does not
|
||||||
|
invalidate such permission if you have separately received it.
|
||||||
|
|
||||||
|
d) If the work has interactive user interfaces, each must display
|
||||||
|
Appropriate Legal Notices; however, if the Program has interactive
|
||||||
|
interfaces that do not display Appropriate Legal Notices, your
|
||||||
|
work need not make them do so.
|
||||||
|
|
||||||
|
A compilation of a covered work with other separate and independent
|
||||||
|
works, which are not by their nature extensions of the covered work,
|
||||||
|
and which are not combined with it such as to form a larger program,
|
||||||
|
in or on a volume of a storage or distribution medium, is called an
|
||||||
|
"aggregate" if the compilation and its resulting copyright are not
|
||||||
|
used to limit the access or legal rights of the compilation's users
|
||||||
|
beyond what the individual works permit. Inclusion of a covered work
|
||||||
|
in an aggregate does not cause this License to apply to the other
|
||||||
|
parts of the aggregate.
|
||||||
|
|
||||||
|
6. Conveying Non-Source Forms.
|
||||||
|
|
||||||
|
You may convey a covered work in object code form under the terms
|
||||||
|
of sections 4 and 5, provided that you also convey the
|
||||||
|
machine-readable Corresponding Source under the terms of this License,
|
||||||
|
in one of these ways:
|
||||||
|
|
||||||
|
a) Convey the object code in, or embodied in, a physical product
|
||||||
|
(including a physical distribution medium), accompanied by the
|
||||||
|
Corresponding Source fixed on a durable physical medium
|
||||||
|
customarily used for software interchange.
|
||||||
|
|
||||||
|
b) Convey the object code in, or embodied in, a physical product
|
||||||
|
(including a physical distribution medium), accompanied by a
|
||||||
|
written offer, valid for at least three years and valid for as
|
||||||
|
long as you offer spare parts or customer support for that product
|
||||||
|
model, to give anyone who possesses the object code either (1) a
|
||||||
|
copy of the Corresponding Source for all the software in the
|
||||||
|
product that is covered by this License, on a durable physical
|
||||||
|
medium customarily used for software interchange, for a price no
|
||||||
|
more than your reasonable cost of physically performing this
|
||||||
|
conveying of source, or (2) access to copy the
|
||||||
|
Corresponding Source from a network server at no charge.
|
||||||
|
|
||||||
|
c) Convey individual copies of the object code with a copy of the
|
||||||
|
written offer to provide the Corresponding Source. This
|
||||||
|
alternative is allowed only occasionally and noncommercially, and
|
||||||
|
only if you received the object code with such an offer, in accord
|
||||||
|
with subsection 6b.
|
||||||
|
|
||||||
|
d) Convey the object code by offering access from a designated
|
||||||
|
place (gratis or for a charge), and offer equivalent access to the
|
||||||
|
Corresponding Source in the same way through the same place at no
|
||||||
|
further charge. You need not require recipients to copy the
|
||||||
|
Corresponding Source along with the object code. If the place to
|
||||||
|
copy the object code is a network server, the Corresponding Source
|
||||||
|
may be on a different server (operated by you or a third party)
|
||||||
|
that supports equivalent copying facilities, provided you maintain
|
||||||
|
clear directions next to the object code saying where to find the
|
||||||
|
Corresponding Source. Regardless of what server hosts the
|
||||||
|
Corresponding Source, you remain obligated to ensure that it is
|
||||||
|
available for as long as needed to satisfy these requirements.
|
||||||
|
|
||||||
|
e) Convey the object code using peer-to-peer transmission, provided
|
||||||
|
you inform other peers where the object code and Corresponding
|
||||||
|
Source of the work are being offered to the general public at no
|
||||||
|
charge under subsection 6d.
|
||||||
|
|
||||||
|
A separable portion of the object code, whose source code is excluded
|
||||||
|
from the Corresponding Source as a System Library, need not be
|
||||||
|
included in conveying the object code work.
|
||||||
|
|
||||||
|
A "User Product" is either (1) a "consumer product", which means any
|
||||||
|
tangible personal property which is normally used for personal, family,
|
||||||
|
or household purposes, or (2) anything designed or sold for incorporation
|
||||||
|
into a dwelling. In determining whether a product is a consumer product,
|
||||||
|
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||||
|
product received by a particular user, "normally used" refers to a
|
||||||
|
typical or common use of that class of product, regardless of the status
|
||||||
|
of the particular user or of the way in which the particular user
|
||||||
|
actually uses, or expects or is expected to use, the product. A product
|
||||||
|
is a consumer product regardless of whether the product has substantial
|
||||||
|
commercial, industrial or non-consumer uses, unless such uses represent
|
||||||
|
the only significant mode of use of the product.
|
||||||
|
|
||||||
|
"Installation Information" for a User Product means any methods,
|
||||||
|
procedures, authorization keys, or other information required to install
|
||||||
|
and execute modified versions of a covered work in that User Product from
|
||||||
|
a modified version of its Corresponding Source. The information must
|
||||||
|
suffice to ensure that the continued functioning of the modified object
|
||||||
|
code is in no case prevented or interfered with solely because
|
||||||
|
modification has been made.
|
||||||
|
|
||||||
|
If you convey an object code work under this section in, or with, or
|
||||||
|
specifically for use in, a User Product, and the conveying occurs as
|
||||||
|
part of a transaction in which the right of possession and use of the
|
||||||
|
User Product is transferred to the recipient in perpetuity or for a
|
||||||
|
fixed term (regardless of how the transaction is characterized), the
|
||||||
|
Corresponding Source conveyed under this section must be accompanied
|
||||||
|
by the Installation Information. But this requirement does not apply
|
||||||
|
if neither you nor any third party retains the ability to install
|
||||||
|
modified object code on the User Product (for example, the work has
|
||||||
|
been installed in ROM).
|
||||||
|
|
||||||
|
The requirement to provide Installation Information does not include a
|
||||||
|
requirement to continue to provide support service, warranty, or updates
|
||||||
|
for a work that has been modified or installed by the recipient, or for
|
||||||
|
the User Product in which it has been modified or installed. Access to a
|
||||||
|
network may be denied when the modification itself materially and
|
||||||
|
adversely affects the operation of the network or violates the rules and
|
||||||
|
protocols for communication across the network.
|
||||||
|
|
||||||
|
Corresponding Source conveyed, and Installation Information provided,
|
||||||
|
in accord with this section must be in a format that is publicly
|
||||||
|
documented (and with an implementation available to the public in
|
||||||
|
source code form), and must require no special password or key for
|
||||||
|
unpacking, reading or copying.
|
||||||
|
|
||||||
|
7. Additional Terms.
|
||||||
|
|
||||||
|
"Additional permissions" are terms that supplement the terms of this
|
||||||
|
License by making exceptions from one or more of its conditions.
|
||||||
|
Additional permissions that are applicable to the entire Program shall
|
||||||
|
be treated as though they were included in this License, to the extent
|
||||||
|
that they are valid under applicable law. If additional permissions
|
||||||
|
apply only to part of the Program, that part may be used separately
|
||||||
|
under those permissions, but the entire Program remains governed by
|
||||||
|
this License without regard to the additional permissions.
|
||||||
|
|
||||||
|
When you convey a copy of a covered work, you may at your option
|
||||||
|
remove any additional permissions from that copy, or from any part of
|
||||||
|
it. (Additional permissions may be written to require their own
|
||||||
|
removal in certain cases when you modify the work.) You may place
|
||||||
|
additional permissions on material, added by you to a covered work,
|
||||||
|
for which you have or can give appropriate copyright permission.
|
||||||
|
|
||||||
|
Notwithstanding any other provision of this License, for material you
|
||||||
|
add to a covered work, you may (if authorized by the copyright holders of
|
||||||
|
that material) supplement the terms of this License with terms:
|
||||||
|
|
||||||
|
a) Disclaiming warranty or limiting liability differently from the
|
||||||
|
terms of sections 15 and 16 of this License; or
|
||||||
|
|
||||||
|
b) Requiring preservation of specified reasonable legal notices or
|
||||||
|
author attributions in that material or in the Appropriate Legal
|
||||||
|
Notices displayed by works containing it; or
|
||||||
|
|
||||||
|
c) Prohibiting misrepresentation of the origin of that material, or
|
||||||
|
requiring that modified versions of such material be marked in
|
||||||
|
reasonable ways as different from the original version; or
|
||||||
|
|
||||||
|
d) Limiting the use for publicity purposes of names of licensors or
|
||||||
|
authors of the material; or
|
||||||
|
|
||||||
|
e) Declining to grant rights under trademark law for use of some
|
||||||
|
trade names, trademarks, or service marks; or
|
||||||
|
|
||||||
|
f) Requiring indemnification of licensors and authors of that
|
||||||
|
material by anyone who conveys the material (or modified versions of
|
||||||
|
it) with contractual assumptions of liability to the recipient, for
|
||||||
|
any liability that these contractual assumptions directly impose on
|
||||||
|
those licensors and authors.
|
||||||
|
|
||||||
|
All other non-permissive additional terms are considered "further
|
||||||
|
restrictions" within the meaning of section 10. If the Program as you
|
||||||
|
received it, or any part of it, contains a notice stating that it is
|
||||||
|
governed by this License along with a term that is a further
|
||||||
|
restriction, you may remove that term. If a license document contains
|
||||||
|
a further restriction but permits relicensing or conveying under this
|
||||||
|
License, you may add to a covered work material governed by the terms
|
||||||
|
of that license document, provided that the further restriction does
|
||||||
|
not survive such relicensing or conveying.
|
||||||
|
|
||||||
|
If you add terms to a covered work in accord with this section, you
|
||||||
|
must place, in the relevant source files, a statement of the
|
||||||
|
additional terms that apply to those files, or a notice indicating
|
||||||
|
where to find the applicable terms.
|
||||||
|
|
||||||
|
Additional terms, permissive or non-permissive, may be stated in the
|
||||||
|
form of a separately written license, or stated as exceptions;
|
||||||
|
the above requirements apply either way.
|
||||||
|
|
||||||
|
8. Termination.
|
||||||
|
|
||||||
|
You may not propagate or modify a covered work except as expressly
|
||||||
|
provided under this License. Any attempt otherwise to propagate or
|
||||||
|
modify it is void, and will automatically terminate your rights under
|
||||||
|
this License (including any patent licenses granted under the third
|
||||||
|
paragraph of section 11).
|
||||||
|
|
||||||
|
However, if you cease all violation of this License, then your
|
||||||
|
license from a particular copyright holder is reinstated (a)
|
||||||
|
provisionally, unless and until the copyright holder explicitly and
|
||||||
|
finally terminates your license, and (b) permanently, if the copyright
|
||||||
|
holder fails to notify you of the violation by some reasonable means
|
||||||
|
prior to 60 days after the cessation.
|
||||||
|
|
||||||
|
Moreover, your license from a particular copyright holder is
|
||||||
|
reinstated permanently if the copyright holder notifies you of the
|
||||||
|
violation by some reasonable means, this is the first time you have
|
||||||
|
received notice of violation of this License (for any work) from that
|
||||||
|
copyright holder, and you cure the violation prior to 30 days after
|
||||||
|
your receipt of the notice.
|
||||||
|
|
||||||
|
Termination of your rights under this section does not terminate the
|
||||||
|
licenses of parties who have received copies or rights from you under
|
||||||
|
this License. If your rights have been terminated and not permanently
|
||||||
|
reinstated, you do not qualify to receive new licenses for the same
|
||||||
|
material under section 10.
|
||||||
|
|
||||||
|
9. Acceptance Not Required for Having Copies.
|
||||||
|
|
||||||
|
You are not required to accept this License in order to receive or
|
||||||
|
run a copy of the Program. Ancillary propagation of a covered work
|
||||||
|
occurring solely as a consequence of using peer-to-peer transmission
|
||||||
|
to receive a copy likewise does not require acceptance. However,
|
||||||
|
nothing other than this License grants you permission to propagate or
|
||||||
|
modify any covered work. These actions infringe copyright if you do
|
||||||
|
not accept this License. Therefore, by modifying or propagating a
|
||||||
|
covered work, you indicate your acceptance of this License to do so.
|
||||||
|
|
||||||
|
10. Automatic Licensing of Downstream Recipients.
|
||||||
|
|
||||||
|
Each time you convey a covered work, the recipient automatically
|
||||||
|
receives a license from the original licensors, to run, modify and
|
||||||
|
propagate that work, subject to this License. You are not responsible
|
||||||
|
for enforcing compliance by third parties with this License.
|
||||||
|
|
||||||
|
An "entity transaction" is a transaction transferring control of an
|
||||||
|
organization, or substantially all assets of one, or subdividing an
|
||||||
|
organization, or merging organizations. If propagation of a covered
|
||||||
|
work results from an entity transaction, each party to that
|
||||||
|
transaction who receives a copy of the work also receives whatever
|
||||||
|
licenses to the work the party's predecessor in interest had or could
|
||||||
|
give under the previous paragraph, plus a right to possession of the
|
||||||
|
Corresponding Source of the work from the predecessor in interest, if
|
||||||
|
the predecessor has it or can get it with reasonable efforts.
|
||||||
|
|
||||||
|
You may not impose any further restrictions on the exercise of the
|
||||||
|
rights granted or affirmed under this License. For example, you may
|
||||||
|
not impose a license fee, royalty, or other charge for exercise of
|
||||||
|
rights granted under this License, and you may not initiate litigation
|
||||||
|
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||||
|
any patent claim is infringed by making, using, selling, offering for
|
||||||
|
sale, or importing the Program or any portion of it.
|
||||||
|
|
||||||
|
11. Patents.
|
||||||
|
|
||||||
|
A "contributor" is a copyright holder who authorizes use under this
|
||||||
|
License of the Program or a work on which the Program is based. The
|
||||||
|
work thus licensed is called the contributor's "contributor version".
|
||||||
|
|
||||||
|
A contributor's "essential patent claims" are all patent claims
|
||||||
|
owned or controlled by the contributor, whether already acquired or
|
||||||
|
hereafter acquired, that would be infringed by some manner, permitted
|
||||||
|
by this License, of making, using, or selling its contributor version,
|
||||||
|
but do not include claims that would be infringed only as a
|
||||||
|
consequence of further modification of the contributor version. For
|
||||||
|
purposes of this definition, "control" includes the right to grant
|
||||||
|
patent sublicenses in a manner consistent with the requirements of
|
||||||
|
this License.
|
||||||
|
|
||||||
|
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||||
|
patent license under the contributor's essential patent claims, to
|
||||||
|
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||||
|
propagate the contents of its contributor version.
|
||||||
|
|
||||||
|
In the following three paragraphs, a "patent license" is any express
|
||||||
|
agreement or commitment, however denominated, not to enforce a patent
|
||||||
|
(such as an express permission to practice a patent or covenant not to
|
||||||
|
sue for patent infringement). To "grant" such a patent license to a
|
||||||
|
party means to make such an agreement or commitment not to enforce a
|
||||||
|
patent against the party.
|
||||||
|
|
||||||
|
If you convey a covered work, knowingly relying on a patent license,
|
||||||
|
and the Corresponding Source of the work is not available for anyone
|
||||||
|
to copy, free of charge and under the terms of this License, through a
|
||||||
|
publicly available network server or other readily accessible means,
|
||||||
|
then you must either (1) cause the Corresponding Source to be so
|
||||||
|
available, or (2) arrange to deprive yourself of the benefit of the
|
||||||
|
patent license for this particular work, or (3) arrange, in a manner
|
||||||
|
consistent with the requirements of this License, to extend the patent
|
||||||
|
license to downstream recipients. "Knowingly relying" means you have
|
||||||
|
actual knowledge that, but for the patent license, your conveying the
|
||||||
|
covered work in a country, or your recipient's use of the covered work
|
||||||
|
in a country, would infringe one or more identifiable patents in that
|
||||||
|
country that you have reason to believe are valid.
|
||||||
|
|
||||||
|
If, pursuant to or in connection with a single transaction or
|
||||||
|
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||||
|
covered work, and grant a patent license to some of the parties
|
||||||
|
receiving the covered work authorizing them to use, propagate, modify
|
||||||
|
or convey a specific copy of the covered work, then the patent license
|
||||||
|
you grant is automatically extended to all recipients of the covered
|
||||||
|
work and works based on it.
|
||||||
|
|
||||||
|
A patent license is "discriminatory" if it does not include within
|
||||||
|
the scope of its coverage, prohibits the exercise of, or is
|
||||||
|
conditioned on the non-exercise of one or more of the rights that are
|
||||||
|
specifically granted under this License. You may not convey a covered
|
||||||
|
work if you are a party to an arrangement with a third party that is
|
||||||
|
in the business of distributing software, under which you make payment
|
||||||
|
to the third party based on the extent of your activity of conveying
|
||||||
|
the work, and under which the third party grants, to any of the
|
||||||
|
parties who would receive the covered work from you, a discriminatory
|
||||||
|
patent license (a) in connection with copies of the covered work
|
||||||
|
conveyed by you (or copies made from those copies), or (b) primarily
|
||||||
|
for and in connection with specific products or compilations that
|
||||||
|
contain the covered work, unless you entered into that arrangement,
|
||||||
|
or that patent license was granted, prior to 28 March 2007.
|
||||||
|
|
||||||
|
Nothing in this License shall be construed as excluding or limiting
|
||||||
|
any implied license or other defenses to infringement that may
|
||||||
|
otherwise be available to you under applicable patent law.
|
||||||
|
|
||||||
|
12. No Surrender of Others' Freedom.
|
||||||
|
|
||||||
|
If conditions are imposed on you (whether by court order, agreement or
|
||||||
|
otherwise) that contradict the conditions of this License, they do not
|
||||||
|
excuse you from the conditions of this License. If you cannot convey a
|
||||||
|
covered work so as to satisfy simultaneously your obligations under this
|
||||||
|
License and any other pertinent obligations, then as a consequence you may
|
||||||
|
not convey it at all. For example, if you agree to terms that obligate you
|
||||||
|
to collect a royalty for further conveying from those to whom you convey
|
||||||
|
the Program, the only way you could satisfy both those terms and this
|
||||||
|
License would be to refrain entirely from conveying the Program.
|
||||||
|
|
||||||
|
13. Use with the GNU Affero General Public License.
|
||||||
|
|
||||||
|
Notwithstanding any other provision of this License, you have
|
||||||
|
permission to link or combine any covered work with a work licensed
|
||||||
|
under version 3 of the GNU Affero General Public License into a single
|
||||||
|
combined work, and to convey the resulting work. The terms of this
|
||||||
|
License will continue to apply to the part which is the covered work,
|
||||||
|
but the special requirements of the GNU Affero General Public License,
|
||||||
|
section 13, concerning interaction through a network will apply to the
|
||||||
|
combination as such.
|
||||||
|
|
||||||
|
14. Revised Versions of this License.
|
||||||
|
|
||||||
|
The Free Software Foundation may publish revised and/or new versions of
|
||||||
|
the GNU General Public License from time to time. Such new versions will
|
||||||
|
be similar in spirit to the present version, but may differ in detail to
|
||||||
|
address new problems or concerns.
|
||||||
|
|
||||||
|
Each version is given a distinguishing version number. If the
|
||||||
|
Program specifies that a certain numbered version of the GNU General
|
||||||
|
Public License "or any later version" applies to it, you have the
|
||||||
|
option of following the terms and conditions either of that numbered
|
||||||
|
version or of any later version published by the Free Software
|
||||||
|
Foundation. If the Program does not specify a version number of the
|
||||||
|
GNU General Public License, you may choose any version ever published
|
||||||
|
by the Free Software Foundation.
|
||||||
|
|
||||||
|
If the Program specifies that a proxy can decide which future
|
||||||
|
versions of the GNU General Public License can be used, that proxy's
|
||||||
|
public statement of acceptance of a version permanently authorizes you
|
||||||
|
to choose that version for the Program.
|
||||||
|
|
||||||
|
Later license versions may give you additional or different
|
||||||
|
permissions. However, no additional obligations are imposed on any
|
||||||
|
author or copyright holder as a result of your choosing to follow a
|
||||||
|
later version.
|
||||||
|
|
||||||
|
15. Disclaimer of Warranty.
|
||||||
|
|
||||||
|
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||||
|
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||||
|
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||||
|
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||||
|
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||||
|
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||||
|
|
||||||
|
16. Limitation of Liability.
|
||||||
|
|
||||||
|
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||||
|
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||||
|
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||||
|
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||||
|
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||||
|
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||||
|
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||||
|
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||||
|
SUCH DAMAGES.
|
||||||
|
|
||||||
|
17. Interpretation of Sections 15 and 16.
|
||||||
|
|
||||||
|
If the disclaimer of warranty and limitation of liability provided
|
||||||
|
above cannot be given local legal effect according to their terms,
|
||||||
|
reviewing courts shall apply local law that most closely approximates
|
||||||
|
an absolute waiver of all civil liability in connection with the
|
||||||
|
Program, unless a warranty or assumption of liability accompanies a
|
||||||
|
copy of the Program in return for a fee.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
How to Apply These Terms to Your New Programs
|
||||||
|
|
||||||
|
If you develop a new program, and you want it to be of the greatest
|
||||||
|
possible use to the public, the best way to achieve this is to make it
|
||||||
|
free software which everyone can redistribute and change under these terms.
|
||||||
|
|
||||||
|
To do so, attach the following notices to the program. It is safest
|
||||||
|
to attach them to the start of each source file to most effectively
|
||||||
|
state the exclusion of warranty; and each file should have at least
|
||||||
|
the "copyright" line and a pointer to where the full notice is found.
|
||||||
|
|
||||||
|
{one line to give the program's name and a brief idea of what it does.}
|
||||||
|
Copyright (C) {year} {name of author}
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
Also add information on how to contact you by electronic and paper mail.
|
||||||
|
|
||||||
|
If the program does terminal interaction, make it output a short
|
||||||
|
notice like this when it starts in an interactive mode:
|
||||||
|
|
||||||
|
{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
|
||||||
|
<http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
The GNU General Public License does not permit incorporating your program
|
||||||
|
into proprietary programs. If your program is a subroutine library, you
|
||||||
|
may consider it more useful to permit linking proprietary applications with
|
||||||
|
the library. If this is what you want to do, use the GNU Lesser General
|
||||||
|
Public License instead of this License. But first, please read
|
||||||
|
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
|
21
vendor/github.com/robotn/gohook/README.md
generated
vendored
Normal file
21
vendor/github.com/robotn/gohook/README.md
generated
vendored
Normal file
@ -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...")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
252
vendor/github.com/robotn/gohook/event/goEvent.h
generated
vendored
Normal file
252
vendor/github.com/robotn/gohook/event/goEvent.h
generated
vendored
Normal file
@ -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 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include <config.h>
|
||||||
|
#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;
|
||||||
|
}
|
49
vendor/github.com/robotn/gohook/event/os.h
generated
vendored
Normal file
49
vendor/github.com/robotn/gohook/event/os.h
generated
vendored
Normal file
@ -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 <windows.h>
|
||||||
|
#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 <stddef.h> */
|
||||||
|
/* #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 */
|
95
vendor/github.com/robotn/gohook/event/pub.h
generated
vendored
Normal file
95
vendor/github.com/robotn/gohook/event/pub.h
generated
vendored
Normal file
@ -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 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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 <inttypes.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#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;
|
||||||
|
}
|
35
vendor/github.com/robotn/gohook/hook.go
generated
vendored
Normal file
35
vendor/github.com/robotn/gohook/hook.go
generated
vendored
Normal file
@ -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()
|
||||||
|
}
|
235
vendor/github.com/robotn/gohook/hook/darwin/event_c.h
generated
vendored
Normal file
235
vendor/github.com/robotn/gohook/hook/darwin/event_c.h
generated
vendored
Normal file
@ -0,0 +1,235 @@
|
|||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <ApplicationServices/ApplicationServices.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#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;
|
||||||
|
}
|
||||||
|
}
|
1362
vendor/github.com/robotn/gohook/hook/darwin/hook_c.h
generated
vendored
Normal file
1362
vendor/github.com/robotn/gohook/hook/darwin/hook_c.h
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
103
vendor/github.com/robotn/gohook/hook/darwin/input.h
generated
vendored
Normal file
103
vendor/github.com/robotn/gohook/hook/darwin/input.h
generated
vendored
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
|
||||||
|
#ifndef _included_input_helper
|
||||||
|
#define _included_input_helper
|
||||||
|
|
||||||
|
#include <ApplicationServices/ApplicationServices.h>
|
||||||
|
#include <Carbon/Carbon.h> // For HIToolbox kVK_ keycodes and TIS funcitons.
|
||||||
|
#ifdef USE_IOKIT
|
||||||
|
#include <IOKit/hidsystem/ev_keymap.h>
|
||||||
|
#endif
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
|
||||||
|
#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
|
542
vendor/github.com/robotn/gohook/hook/darwin/input_c.h
generated
vendored
Normal file
542
vendor/github.com/robotn/gohook/hook/darwin/input_c.h
generated
vendored
Normal file
@ -0,0 +1,542 @@
|
|||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_COREFOUNDATION
|
||||||
|
#include <CoreFoundation/CoreFoundation.h>
|
||||||
|
#endif
|
||||||
|
#ifndef USE_WEAK_IMPORT
|
||||||
|
#include <dlfcn.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#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
|
||||||
|
}
|
522
vendor/github.com/robotn/gohook/hook/darwin/properties_c.h
generated
vendored
Normal file
522
vendor/github.com/robotn/gohook/hook/darwin/properties_c.h
generated
vendored
Normal file
@ -0,0 +1,522 @@
|
|||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_CARBON_LEGACY
|
||||||
|
#include <Carbon/Carbon.h>
|
||||||
|
#endif
|
||||||
|
#ifdef USE_COREFOUNDATION
|
||||||
|
#include <CoreFoundation/CoreFoundation.h>
|
||||||
|
#endif
|
||||||
|
#ifdef USE_IOKIT
|
||||||
|
#include <IOKit/hidsystem/IOHIDLib.h>
|
||||||
|
#include <IOKit/hidsystem/IOHIDParameter.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#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();
|
||||||
|
}
|
441
vendor/github.com/robotn/gohook/hook/iohook.h
generated
vendored
Normal file
441
vendor/github.com/robotn/gohook/hook/iohook.h
generated
vendored
Normal file
@ -0,0 +1,441 @@
|
|||||||
|
|
||||||
|
#ifndef __IOHOOK_H
|
||||||
|
#define __IOHOOK_H
|
||||||
|
|
||||||
|
// #include "../../base/os.h"
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
/* 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
|
15
vendor/github.com/robotn/gohook/hook/logger.h
generated
vendored
Normal file
15
vendor/github.com/robotn/gohook/hook/logger.h
generated
vendored
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
|
||||||
|
#ifndef _included_logger
|
||||||
|
#define _included_logger
|
||||||
|
|
||||||
|
#include "iohook.h"
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#ifndef __FUNCTION__
|
||||||
|
#define __FUNCTION__ __func__
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// logger(level, message)
|
||||||
|
extern logger_t logger;
|
||||||
|
|
||||||
|
#endif
|
53
vendor/github.com/robotn/gohook/hook/logger_c.h
generated
vendored
Normal file
53
vendor/github.com/robotn/gohook/hook/logger_c.h
generated
vendored
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#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;
|
||||||
|
}
|
||||||
|
}
|
328
vendor/github.com/robotn/gohook/hook/windows/event_c.h
generated
vendored
Normal file
328
vendor/github.com/robotn/gohook/hook/windows/event_c.h
generated
vendored
Normal file
@ -0,0 +1,328 @@
|
|||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "../iohook.h"
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
// #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);
|
||||||
|
}
|
747
vendor/github.com/robotn/gohook/hook/windows/hook_c.h
generated
vendored
Normal file
747
vendor/github.com/robotn/gohook/hook/windows/hook_c.h
generated
vendored
Normal file
@ -0,0 +1,747 @@
|
|||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
#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;
|
||||||
|
}
|
104
vendor/github.com/robotn/gohook/hook/windows/input.h
generated
vendored
Normal file
104
vendor/github.com/robotn/gohook/hook/windows/input.h
generated
vendored
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
/***********************************************************************
|
||||||
|
Input
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
#ifndef _included_input_helper
|
||||||
|
#define _included_input_helper
|
||||||
|
|
||||||
|
#include <limits.h>
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
#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
|
832
vendor/github.com/robotn/gohook/hook/windows/input_c.h
generated
vendored
Normal file
832
vendor/github.com/robotn/gohook/hook/windows/input_c.h
generated
vendored
Normal file
@ -0,0 +1,832 @@
|
|||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
#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;
|
||||||
|
}
|
211
vendor/github.com/robotn/gohook/hook/windows/properties_c.h
generated
vendored
Normal file
211
vendor/github.com/robotn/gohook/hook/windows/properties_c.h
generated
vendored
Normal file
@ -0,0 +1,211 @@
|
|||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
#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;
|
||||||
|
}
|
386
vendor/github.com/robotn/gohook/hook/x11/event_c.h
generated
vendored
Normal file
386
vendor/github.com/robotn/gohook/hook/x11/event_c.h
generated
vendored
Normal file
@ -0,0 +1,386 @@
|
|||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <X11/Xlib.h>
|
||||||
|
#include <X11/Xutil.h>
|
||||||
|
#ifdef USE_XTEST
|
||||||
|
#include <X11/extensions/XTest.h>
|
||||||
|
#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);
|
||||||
|
}
|
1132
vendor/github.com/robotn/gohook/hook/x11/hook_c.h
generated
vendored
Normal file
1132
vendor/github.com/robotn/gohook/hook/x11/hook_c.h
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
86
vendor/github.com/robotn/gohook/hook/x11/input.h
generated
vendored
Normal file
86
vendor/github.com/robotn/gohook/hook/x11/input.h
generated
vendored
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
|
||||||
|
#define USE_XKBCOMMON 0
|
||||||
|
//#define _included_input_helper 0
|
||||||
|
#ifndef _included_input_helper
|
||||||
|
#define _included_input_helper
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <X11/Xlib.h>
|
||||||
|
|
||||||
|
#ifdef USE_XKBCOMMON
|
||||||
|
#include <X11/Xlib-xcb.h>
|
||||||
|
#include <xkbcommon/xkbcommon.h>
|
||||||
|
#include <xkbcommon/xkbcommon-x11.h>
|
||||||
|
#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
|
1970
vendor/github.com/robotn/gohook/hook/x11/input_c.h
generated
vendored
Normal file
1970
vendor/github.com/robotn/gohook/hook/x11/input_c.h
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
499
vendor/github.com/robotn/gohook/hook/x11/properties_c.h
generated
vendored
Normal file
499
vendor/github.com/robotn/gohook/hook/x11/properties_c.h
generated
vendored
Normal file
@ -0,0 +1,499 @@
|
|||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <X11/Xlib.h>
|
||||||
|
#ifdef USE_XKB
|
||||||
|
#include <X11/XKBlib.h>
|
||||||
|
#endif
|
||||||
|
#ifdef USE_XF86MISC
|
||||||
|
#include <X11/extensions/xf86misc.h>
|
||||||
|
#include <X11/extensions/xf86mscstr.h>
|
||||||
|
#endif
|
||||||
|
#if defined(USE_XINERAMA) && !defined(USE_XRANDR)
|
||||||
|
#include <X11/extensions/Xinerama.h>
|
||||||
|
#elif defined(USE_XRANDR)
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <X11/extensions/Xrandr.h>
|
||||||
|
#endif
|
||||||
|
#ifdef USE_XT
|
||||||
|
#include <X11/Intrinsic.h>
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
1
vendor/golang.org/x/sys/unix/mkerrors.sh
generated
vendored
1
vendor/golang.org/x/sys/unix/mkerrors.sh
generated
vendored
@ -456,6 +456,7 @@ ccflags="$@"
|
|||||||
$2 ~ /^PERF_EVENT_IOC_/ ||
|
$2 ~ /^PERF_EVENT_IOC_/ ||
|
||||||
$2 ~ /^SECCOMP_MODE_/ ||
|
$2 ~ /^SECCOMP_MODE_/ ||
|
||||||
$2 ~ /^SPLICE_/ ||
|
$2 ~ /^SPLICE_/ ||
|
||||||
|
$2 ~ /^SYNC_FILE_RANGE_/ ||
|
||||||
$2 !~ /^AUDIT_RECORD_MAGIC/ &&
|
$2 !~ /^AUDIT_RECORD_MAGIC/ &&
|
||||||
$2 !~ /IOC_MAGIC/ &&
|
$2 !~ /IOC_MAGIC/ &&
|
||||||
$2 ~ /^[A-Z][A-Z0-9_]+_MAGIC2?$/ ||
|
$2 ~ /^[A-Z][A-Z0-9_]+_MAGIC2?$/ ||
|
||||||
|
9
vendor/golang.org/x/sys/unix/syscall_linux_ppc64x.go
generated
vendored
9
vendor/golang.org/x/sys/unix/syscall_linux_ppc64x.go
generated
vendored
@ -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 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 Stat(path string, stat *Stat_t) (err error)
|
||||||
//sys Statfs(path string, buf *Statfs_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 Truncate(path string, length int64) (err error)
|
||||||
//sys Ustat(dev int, ubuf *Ustat_t) (err error)
|
//sys Ustat(dev int, ubuf *Ustat_t) (err error)
|
||||||
//sys accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, 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)
|
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)
|
||||||
|
}
|
||||||
|
212
vendor/golang.org/x/sys/unix/syscall_linux_riscv64.go
generated
vendored
Normal file
212
vendor/golang.org/x/sys/unix/syscall_linux_riscv64.go
generated
vendored
Normal file
@ -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)
|
||||||
|
}
|
3
vendor/golang.org/x/sys/unix/zerrors_linux_386.go
generated
vendored
3
vendor/golang.org/x/sys/unix/zerrors_linux_386.go
generated
vendored
@ -1891,6 +1891,9 @@ const (
|
|||||||
STATX_TYPE = 0x1
|
STATX_TYPE = 0x1
|
||||||
STATX_UID = 0x8
|
STATX_UID = 0x8
|
||||||
STATX__RESERVED = 0x80000000
|
STATX__RESERVED = 0x80000000
|
||||||
|
SYNC_FILE_RANGE_WAIT_AFTER = 0x4
|
||||||
|
SYNC_FILE_RANGE_WAIT_BEFORE = 0x1
|
||||||
|
SYNC_FILE_RANGE_WRITE = 0x2
|
||||||
SYSFS_MAGIC = 0x62656572
|
SYSFS_MAGIC = 0x62656572
|
||||||
S_BLKSIZE = 0x200
|
S_BLKSIZE = 0x200
|
||||||
S_IEXEC = 0x40
|
S_IEXEC = 0x40
|
||||||
|
3
vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go
generated
vendored
3
vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go
generated
vendored
@ -1892,6 +1892,9 @@ const (
|
|||||||
STATX_TYPE = 0x1
|
STATX_TYPE = 0x1
|
||||||
STATX_UID = 0x8
|
STATX_UID = 0x8
|
||||||
STATX__RESERVED = 0x80000000
|
STATX__RESERVED = 0x80000000
|
||||||
|
SYNC_FILE_RANGE_WAIT_AFTER = 0x4
|
||||||
|
SYNC_FILE_RANGE_WAIT_BEFORE = 0x1
|
||||||
|
SYNC_FILE_RANGE_WRITE = 0x2
|
||||||
SYSFS_MAGIC = 0x62656572
|
SYSFS_MAGIC = 0x62656572
|
||||||
S_BLKSIZE = 0x200
|
S_BLKSIZE = 0x200
|
||||||
S_IEXEC = 0x40
|
S_IEXEC = 0x40
|
||||||
|
3
vendor/golang.org/x/sys/unix/zerrors_linux_arm.go
generated
vendored
3
vendor/golang.org/x/sys/unix/zerrors_linux_arm.go
generated
vendored
@ -1898,6 +1898,9 @@ const (
|
|||||||
STATX_TYPE = 0x1
|
STATX_TYPE = 0x1
|
||||||
STATX_UID = 0x8
|
STATX_UID = 0x8
|
||||||
STATX__RESERVED = 0x80000000
|
STATX__RESERVED = 0x80000000
|
||||||
|
SYNC_FILE_RANGE_WAIT_AFTER = 0x4
|
||||||
|
SYNC_FILE_RANGE_WAIT_BEFORE = 0x1
|
||||||
|
SYNC_FILE_RANGE_WRITE = 0x2
|
||||||
SYSFS_MAGIC = 0x62656572
|
SYSFS_MAGIC = 0x62656572
|
||||||
S_BLKSIZE = 0x200
|
S_BLKSIZE = 0x200
|
||||||
S_IEXEC = 0x40
|
S_IEXEC = 0x40
|
||||||
|
3
vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go
generated
vendored
3
vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go
generated
vendored
@ -1883,6 +1883,9 @@ const (
|
|||||||
STATX_UID = 0x8
|
STATX_UID = 0x8
|
||||||
STATX__RESERVED = 0x80000000
|
STATX__RESERVED = 0x80000000
|
||||||
SVE_MAGIC = 0x53564501
|
SVE_MAGIC = 0x53564501
|
||||||
|
SYNC_FILE_RANGE_WAIT_AFTER = 0x4
|
||||||
|
SYNC_FILE_RANGE_WAIT_BEFORE = 0x1
|
||||||
|
SYNC_FILE_RANGE_WRITE = 0x2
|
||||||
SYSFS_MAGIC = 0x62656572
|
SYSFS_MAGIC = 0x62656572
|
||||||
S_BLKSIZE = 0x200
|
S_BLKSIZE = 0x200
|
||||||
S_IEXEC = 0x40
|
S_IEXEC = 0x40
|
||||||
|
3
vendor/golang.org/x/sys/unix/zerrors_linux_mips.go
generated
vendored
3
vendor/golang.org/x/sys/unix/zerrors_linux_mips.go
generated
vendored
@ -1892,6 +1892,9 @@ const (
|
|||||||
STATX_TYPE = 0x1
|
STATX_TYPE = 0x1
|
||||||
STATX_UID = 0x8
|
STATX_UID = 0x8
|
||||||
STATX__RESERVED = 0x80000000
|
STATX__RESERVED = 0x80000000
|
||||||
|
SYNC_FILE_RANGE_WAIT_AFTER = 0x4
|
||||||
|
SYNC_FILE_RANGE_WAIT_BEFORE = 0x1
|
||||||
|
SYNC_FILE_RANGE_WRITE = 0x2
|
||||||
SYSFS_MAGIC = 0x62656572
|
SYSFS_MAGIC = 0x62656572
|
||||||
S_BLKSIZE = 0x200
|
S_BLKSIZE = 0x200
|
||||||
S_IEXEC = 0x40
|
S_IEXEC = 0x40
|
||||||
|
3
vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go
generated
vendored
3
vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go
generated
vendored
@ -1892,6 +1892,9 @@ const (
|
|||||||
STATX_TYPE = 0x1
|
STATX_TYPE = 0x1
|
||||||
STATX_UID = 0x8
|
STATX_UID = 0x8
|
||||||
STATX__RESERVED = 0x80000000
|
STATX__RESERVED = 0x80000000
|
||||||
|
SYNC_FILE_RANGE_WAIT_AFTER = 0x4
|
||||||
|
SYNC_FILE_RANGE_WAIT_BEFORE = 0x1
|
||||||
|
SYNC_FILE_RANGE_WRITE = 0x2
|
||||||
SYSFS_MAGIC = 0x62656572
|
SYSFS_MAGIC = 0x62656572
|
||||||
S_BLKSIZE = 0x200
|
S_BLKSIZE = 0x200
|
||||||
S_IEXEC = 0x40
|
S_IEXEC = 0x40
|
||||||
|
3
vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go
generated
vendored
3
vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go
generated
vendored
@ -1892,6 +1892,9 @@ const (
|
|||||||
STATX_TYPE = 0x1
|
STATX_TYPE = 0x1
|
||||||
STATX_UID = 0x8
|
STATX_UID = 0x8
|
||||||
STATX__RESERVED = 0x80000000
|
STATX__RESERVED = 0x80000000
|
||||||
|
SYNC_FILE_RANGE_WAIT_AFTER = 0x4
|
||||||
|
SYNC_FILE_RANGE_WAIT_BEFORE = 0x1
|
||||||
|
SYNC_FILE_RANGE_WRITE = 0x2
|
||||||
SYSFS_MAGIC = 0x62656572
|
SYSFS_MAGIC = 0x62656572
|
||||||
S_BLKSIZE = 0x200
|
S_BLKSIZE = 0x200
|
||||||
S_IEXEC = 0x40
|
S_IEXEC = 0x40
|
||||||
|
3
vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go
generated
vendored
3
vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go
generated
vendored
@ -1892,6 +1892,9 @@ const (
|
|||||||
STATX_TYPE = 0x1
|
STATX_TYPE = 0x1
|
||||||
STATX_UID = 0x8
|
STATX_UID = 0x8
|
||||||
STATX__RESERVED = 0x80000000
|
STATX__RESERVED = 0x80000000
|
||||||
|
SYNC_FILE_RANGE_WAIT_AFTER = 0x4
|
||||||
|
SYNC_FILE_RANGE_WAIT_BEFORE = 0x1
|
||||||
|
SYNC_FILE_RANGE_WRITE = 0x2
|
||||||
SYSFS_MAGIC = 0x62656572
|
SYSFS_MAGIC = 0x62656572
|
||||||
S_BLKSIZE = 0x200
|
S_BLKSIZE = 0x200
|
||||||
S_IEXEC = 0x40
|
S_IEXEC = 0x40
|
||||||
|
3
vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go
generated
vendored
3
vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go
generated
vendored
@ -1947,6 +1947,9 @@ const (
|
|||||||
STATX_TYPE = 0x1
|
STATX_TYPE = 0x1
|
||||||
STATX_UID = 0x8
|
STATX_UID = 0x8
|
||||||
STATX__RESERVED = 0x80000000
|
STATX__RESERVED = 0x80000000
|
||||||
|
SYNC_FILE_RANGE_WAIT_AFTER = 0x4
|
||||||
|
SYNC_FILE_RANGE_WAIT_BEFORE = 0x1
|
||||||
|
SYNC_FILE_RANGE_WRITE = 0x2
|
||||||
SYSFS_MAGIC = 0x62656572
|
SYSFS_MAGIC = 0x62656572
|
||||||
S_BLKSIZE = 0x200
|
S_BLKSIZE = 0x200
|
||||||
S_IEXEC = 0x40
|
S_IEXEC = 0x40
|
||||||
|
3
vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go
generated
vendored
3
vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go
generated
vendored
@ -1947,6 +1947,9 @@ const (
|
|||||||
STATX_TYPE = 0x1
|
STATX_TYPE = 0x1
|
||||||
STATX_UID = 0x8
|
STATX_UID = 0x8
|
||||||
STATX__RESERVED = 0x80000000
|
STATX__RESERVED = 0x80000000
|
||||||
|
SYNC_FILE_RANGE_WAIT_AFTER = 0x4
|
||||||
|
SYNC_FILE_RANGE_WAIT_BEFORE = 0x1
|
||||||
|
SYNC_FILE_RANGE_WRITE = 0x2
|
||||||
SYSFS_MAGIC = 0x62656572
|
SYSFS_MAGIC = 0x62656572
|
||||||
S_BLKSIZE = 0x200
|
S_BLKSIZE = 0x200
|
||||||
S_IEXEC = 0x40
|
S_IEXEC = 0x40
|
||||||
|
2625
vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go
generated
vendored
Normal file
2625
vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
3
vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go
generated
vendored
3
vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go
generated
vendored
@ -1952,6 +1952,9 @@ const (
|
|||||||
STATX_TYPE = 0x1
|
STATX_TYPE = 0x1
|
||||||
STATX_UID = 0x8
|
STATX_UID = 0x8
|
||||||
STATX__RESERVED = 0x80000000
|
STATX__RESERVED = 0x80000000
|
||||||
|
SYNC_FILE_RANGE_WAIT_AFTER = 0x4
|
||||||
|
SYNC_FILE_RANGE_WAIT_BEFORE = 0x1
|
||||||
|
SYNC_FILE_RANGE_WRITE = 0x2
|
||||||
SYSFS_MAGIC = 0x62656572
|
SYSFS_MAGIC = 0x62656572
|
||||||
S_BLKSIZE = 0x200
|
S_BLKSIZE = 0x200
|
||||||
S_IEXEC = 0x40
|
S_IEXEC = 0x40
|
||||||
|
20
vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64.go
generated
vendored
20
vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64.go
generated
vendored
@ -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
|
// 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) {
|
func Truncate(path string, length int64) (err error) {
|
||||||
var _p0 *byte
|
var _p0 *byte
|
||||||
_p0, err = BytePtrFromString(path)
|
_p0, err = BytePtrFromString(path)
|
||||||
@ -2317,3 +2307,13 @@ func poll(fds *PollFd, nfds int, timeout int) (n int, err error) {
|
|||||||
}
|
}
|
||||||
return
|
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
|
||||||
|
}
|
||||||
|
20
vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64le.go
generated
vendored
20
vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64le.go
generated
vendored
@ -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
|
// 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) {
|
func Truncate(path string, length int64) (err error) {
|
||||||
var _p0 *byte
|
var _p0 *byte
|
||||||
_p0, err = BytePtrFromString(path)
|
_p0, err = BytePtrFromString(path)
|
||||||
@ -2317,3 +2307,13 @@ func poll(fds *PollFd, nfds int, timeout int) (n int, err error) {
|
|||||||
}
|
}
|
||||||
return
|
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
|
||||||
|
}
|
||||||
|
2114
vendor/golang.org/x/sys/unix/zsyscall_linux_riscv64.go
generated
vendored
Normal file
2114
vendor/golang.org/x/sys/unix/zsyscall_linux_riscv64.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
286
vendor/golang.org/x/sys/unix/zsysnum_linux_riscv64.go
generated
vendored
Normal file
286
vendor/golang.org/x/sys/unix/zsysnum_linux_riscv64.go
generated
vendored
Normal file
@ -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
|
||||||
|
)
|
7
vendor/golang.org/x/sys/unix/ztypes_linux_386.go
generated
vendored
7
vendor/golang.org/x/sys/unix/ztypes_linux_386.go
generated
vendored
@ -510,6 +510,13 @@ const (
|
|||||||
RTA_FLOW = 0xb
|
RTA_FLOW = 0xb
|
||||||
RTA_CACHEINFO = 0xc
|
RTA_CACHEINFO = 0xc
|
||||||
RTA_TABLE = 0xf
|
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_UNSPEC = 0x0
|
||||||
RTN_UNICAST = 0x1
|
RTN_UNICAST = 0x1
|
||||||
RTN_LOCAL = 0x2
|
RTN_LOCAL = 0x2
|
||||||
|
7
vendor/golang.org/x/sys/unix/ztypes_linux_amd64.go
generated
vendored
7
vendor/golang.org/x/sys/unix/ztypes_linux_amd64.go
generated
vendored
@ -514,6 +514,13 @@ const (
|
|||||||
RTA_FLOW = 0xb
|
RTA_FLOW = 0xb
|
||||||
RTA_CACHEINFO = 0xc
|
RTA_CACHEINFO = 0xc
|
||||||
RTA_TABLE = 0xf
|
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_UNSPEC = 0x0
|
||||||
RTN_UNICAST = 0x1
|
RTN_UNICAST = 0x1
|
||||||
RTN_LOCAL = 0x2
|
RTN_LOCAL = 0x2
|
||||||
|
7
vendor/golang.org/x/sys/unix/ztypes_linux_arm.go
generated
vendored
7
vendor/golang.org/x/sys/unix/ztypes_linux_arm.go
generated
vendored
@ -513,6 +513,13 @@ const (
|
|||||||
RTA_FLOW = 0xb
|
RTA_FLOW = 0xb
|
||||||
RTA_CACHEINFO = 0xc
|
RTA_CACHEINFO = 0xc
|
||||||
RTA_TABLE = 0xf
|
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_UNSPEC = 0x0
|
||||||
RTN_UNICAST = 0x1
|
RTN_UNICAST = 0x1
|
||||||
RTN_LOCAL = 0x2
|
RTN_LOCAL = 0x2
|
||||||
|
7
vendor/golang.org/x/sys/unix/ztypes_linux_arm64.go
generated
vendored
7
vendor/golang.org/x/sys/unix/ztypes_linux_arm64.go
generated
vendored
@ -515,6 +515,13 @@ const (
|
|||||||
RTA_FLOW = 0xb
|
RTA_FLOW = 0xb
|
||||||
RTA_CACHEINFO = 0xc
|
RTA_CACHEINFO = 0xc
|
||||||
RTA_TABLE = 0xf
|
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_UNSPEC = 0x0
|
||||||
RTN_UNICAST = 0x1
|
RTN_UNICAST = 0x1
|
||||||
RTN_LOCAL = 0x2
|
RTN_LOCAL = 0x2
|
||||||
|
7
vendor/golang.org/x/sys/unix/ztypes_linux_mips.go
generated
vendored
7
vendor/golang.org/x/sys/unix/ztypes_linux_mips.go
generated
vendored
@ -511,6 +511,13 @@ const (
|
|||||||
RTA_FLOW = 0xb
|
RTA_FLOW = 0xb
|
||||||
RTA_CACHEINFO = 0xc
|
RTA_CACHEINFO = 0xc
|
||||||
RTA_TABLE = 0xf
|
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_UNSPEC = 0x0
|
||||||
RTN_UNICAST = 0x1
|
RTN_UNICAST = 0x1
|
||||||
RTN_LOCAL = 0x2
|
RTN_LOCAL = 0x2
|
||||||
|
7
vendor/golang.org/x/sys/unix/ztypes_linux_mips64.go
generated
vendored
7
vendor/golang.org/x/sys/unix/ztypes_linux_mips64.go
generated
vendored
@ -515,6 +515,13 @@ const (
|
|||||||
RTA_FLOW = 0xb
|
RTA_FLOW = 0xb
|
||||||
RTA_CACHEINFO = 0xc
|
RTA_CACHEINFO = 0xc
|
||||||
RTA_TABLE = 0xf
|
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_UNSPEC = 0x0
|
||||||
RTN_UNICAST = 0x1
|
RTN_UNICAST = 0x1
|
||||||
RTN_LOCAL = 0x2
|
RTN_LOCAL = 0x2
|
||||||
|
7
vendor/golang.org/x/sys/unix/ztypes_linux_mips64le.go
generated
vendored
7
vendor/golang.org/x/sys/unix/ztypes_linux_mips64le.go
generated
vendored
@ -515,6 +515,13 @@ const (
|
|||||||
RTA_FLOW = 0xb
|
RTA_FLOW = 0xb
|
||||||
RTA_CACHEINFO = 0xc
|
RTA_CACHEINFO = 0xc
|
||||||
RTA_TABLE = 0xf
|
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_UNSPEC = 0x0
|
||||||
RTN_UNICAST = 0x1
|
RTN_UNICAST = 0x1
|
||||||
RTN_LOCAL = 0x2
|
RTN_LOCAL = 0x2
|
||||||
|
7
vendor/golang.org/x/sys/unix/ztypes_linux_mipsle.go
generated
vendored
7
vendor/golang.org/x/sys/unix/ztypes_linux_mipsle.go
generated
vendored
@ -511,6 +511,13 @@ const (
|
|||||||
RTA_FLOW = 0xb
|
RTA_FLOW = 0xb
|
||||||
RTA_CACHEINFO = 0xc
|
RTA_CACHEINFO = 0xc
|
||||||
RTA_TABLE = 0xf
|
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_UNSPEC = 0x0
|
||||||
RTN_UNICAST = 0x1
|
RTN_UNICAST = 0x1
|
||||||
RTN_LOCAL = 0x2
|
RTN_LOCAL = 0x2
|
||||||
|
7
vendor/golang.org/x/sys/unix/ztypes_linux_ppc64.go
generated
vendored
7
vendor/golang.org/x/sys/unix/ztypes_linux_ppc64.go
generated
vendored
@ -516,6 +516,13 @@ const (
|
|||||||
RTA_FLOW = 0xb
|
RTA_FLOW = 0xb
|
||||||
RTA_CACHEINFO = 0xc
|
RTA_CACHEINFO = 0xc
|
||||||
RTA_TABLE = 0xf
|
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_UNSPEC = 0x0
|
||||||
RTN_UNICAST = 0x1
|
RTN_UNICAST = 0x1
|
||||||
RTN_LOCAL = 0x2
|
RTN_LOCAL = 0x2
|
||||||
|
7
vendor/golang.org/x/sys/unix/ztypes_linux_ppc64le.go
generated
vendored
7
vendor/golang.org/x/sys/unix/ztypes_linux_ppc64le.go
generated
vendored
@ -516,6 +516,13 @@ const (
|
|||||||
RTA_FLOW = 0xb
|
RTA_FLOW = 0xb
|
||||||
RTA_CACHEINFO = 0xc
|
RTA_CACHEINFO = 0xc
|
||||||
RTA_TABLE = 0xf
|
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_UNSPEC = 0x0
|
||||||
RTN_UNICAST = 0x1
|
RTN_UNICAST = 0x1
|
||||||
RTN_LOCAL = 0x2
|
RTN_LOCAL = 0x2
|
||||||
|
1919
vendor/golang.org/x/sys/unix/ztypes_linux_riscv64.go
generated
vendored
Normal file
1919
vendor/golang.org/x/sys/unix/ztypes_linux_riscv64.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
7
vendor/golang.org/x/sys/unix/ztypes_linux_s390x.go
generated
vendored
7
vendor/golang.org/x/sys/unix/ztypes_linux_s390x.go
generated
vendored
@ -514,6 +514,13 @@ const (
|
|||||||
RTA_FLOW = 0xb
|
RTA_FLOW = 0xb
|
||||||
RTA_CACHEINFO = 0xc
|
RTA_CACHEINFO = 0xc
|
||||||
RTA_TABLE = 0xf
|
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_UNSPEC = 0x0
|
||||||
RTN_UNICAST = 0x1
|
RTN_UNICAST = 0x1
|
||||||
RTN_LOCAL = 0x2
|
RTN_LOCAL = 0x2
|
||||||
|
58
vendor/golang.org/x/sys/windows/syscall_windows.go
generated
vendored
58
vendor/golang.org/x/sys/windows/syscall_windows.go
generated
vendored
@ -655,7 +655,7 @@ type RawSockaddr struct {
|
|||||||
|
|
||||||
type RawSockaddrAny struct {
|
type RawSockaddrAny struct {
|
||||||
Addr RawSockaddr
|
Addr RawSockaddr
|
||||||
Pad [96]int8
|
Pad [100]int8
|
||||||
}
|
}
|
||||||
|
|
||||||
type Sockaddr interface {
|
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
|
return unsafe.Pointer(&sa.raw), int32(unsafe.Sizeof(sa.raw)), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type RawSockaddrUnix struct {
|
||||||
|
Family uint16
|
||||||
|
Path [UNIX_PATH_MAX]int8
|
||||||
|
}
|
||||||
|
|
||||||
type SockaddrUnix struct {
|
type SockaddrUnix struct {
|
||||||
Name string
|
Name string
|
||||||
|
raw RawSockaddrUnix
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sa *SockaddrUnix) sockaddr() (unsafe.Pointer, int32, error) {
|
func (sa *SockaddrUnix) sockaddr() (unsafe.Pointer, int32, error) {
|
||||||
// TODO(brainman): implement SockaddrUnix.sockaddr()
|
name := sa.Name
|
||||||
return nil, 0, syscall.EWINDOWS
|
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) {
|
func (rsa *RawSockaddrAny) Sockaddr() (Sockaddr, error) {
|
||||||
switch rsa.Addr.Family {
|
switch rsa.Addr.Family {
|
||||||
case AF_UNIX:
|
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:
|
case AF_INET:
|
||||||
pp := (*RawSockaddrInet4)(unsafe.Pointer(rsa))
|
pp := (*RawSockaddrInet4)(unsafe.Pointer(rsa))
|
||||||
|
4
vendor/golang.org/x/sys/windows/types_windows.go
generated
vendored
4
vendor/golang.org/x/sys/windows/types_windows.go
generated
vendored
@ -1453,7 +1453,7 @@ type SmallRect struct {
|
|||||||
Bottom int16
|
Bottom int16
|
||||||
}
|
}
|
||||||
|
|
||||||
// Used with GetConsoleScreenBuffer to retreive information about a console
|
// Used with GetConsoleScreenBuffer to retrieve information about a console
|
||||||
// screen buffer. See
|
// screen buffer. See
|
||||||
// https://docs.microsoft.com/en-us/windows/console/console-screen-buffer-info-str
|
// https://docs.microsoft.com/en-us/windows/console/console-screen-buffer-info-str
|
||||||
// for details.
|
// for details.
|
||||||
@ -1465,3 +1465,5 @@ type ConsoleScreenBufferInfo struct {
|
|||||||
Window SmallRect
|
Window SmallRect
|
||||||
MaximumWindowSize Coord
|
MaximumWindowSize Coord
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const UNIX_PATH_MAX = 108 // defined in afunix.h
|
||||||
|
Loading…
Reference in New Issue
Block a user