Moved JNA from Utilites project
commit
490831daeb
|
@ -0,0 +1,121 @@
|
|||
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm
|
||||
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
|
||||
|
||||
# User-specific stuff:
|
||||
.idea/**/workspace.xml
|
||||
.idea/**/tasks.xml
|
||||
.idea/dictionaries
|
||||
.idea/**/codeStyles/
|
||||
.idea/**/codeStyleSettings.xml
|
||||
|
||||
# Sensitive or high-churn files:
|
||||
.idea/**/dataSources/
|
||||
.idea/**/dataSources.ids
|
||||
.idea/**/dataSources.xml
|
||||
.idea/**/dataSources.local.xml
|
||||
.idea/**/sqlDataSources.xml
|
||||
.idea/**/dynamic.xml
|
||||
.idea/**/uiDesigner.xml
|
||||
.idea/**/shelf/
|
||||
|
||||
|
||||
# Gradle:
|
||||
.idea/**/gradle.xml
|
||||
.idea/**/libraries
|
||||
|
||||
# CMake
|
||||
cmake-build-debug/
|
||||
|
||||
# Mongo Explorer plugin:
|
||||
.idea/**/mongoSettings.xml
|
||||
|
||||
## File-based project format:
|
||||
*.iws
|
||||
|
||||
## Plugin-specific files:
|
||||
|
||||
|
||||
# IntelliJ
|
||||
out/
|
||||
|
||||
# mpeltonen/sbt-idea plugin
|
||||
.idea_modules/
|
||||
|
||||
# JIRA plugin
|
||||
atlassian-ide-plugin.xml
|
||||
|
||||
# Cursive Clojure plugin
|
||||
.idea/replstate.xml
|
||||
|
||||
# Crashlytics plugin (for Android Studio and IntelliJ)
|
||||
com_crashlytics_export_strings.xml
|
||||
crashlytics.properties
|
||||
crashlytics-build.properties
|
||||
fabric.properties
|
||||
|
||||
######################
|
||||
# End JetBrains IDEs #
|
||||
######################
|
||||
|
||||
|
||||
# From https://github.com/github/gitignore/blob/master/Gradle.gitignore
|
||||
.gradle
|
||||
/build/
|
||||
|
||||
# Ignore Gradle GUI config
|
||||
gradle-app.setting
|
||||
|
||||
# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored)
|
||||
!gradle-wrapper.jar
|
||||
!gradle-wrapper.properties
|
||||
|
||||
# Cache of project
|
||||
.gradletasknamecache
|
||||
|
||||
|
||||
|
||||
|
||||
# From https://github.com/github/gitignore/blob/master/Java.gitignore
|
||||
*.class
|
||||
|
||||
# Mobile Tools for Java (J2ME)
|
||||
.mtj.tmp/
|
||||
|
||||
|
||||
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
|
||||
hs_err_pid*
|
||||
|
||||
*.DS_Store
|
||||
.AppleDouble
|
||||
.LSOverride
|
||||
|
||||
# Icon must end with two \r
|
||||
Icon
|
||||
|
||||
|
||||
# Thumbnails
|
||||
._*
|
||||
|
||||
# Files that might appear in the root of a volume
|
||||
.DocumentRevisions-V100
|
||||
.fseventsd
|
||||
.Spotlight-V100
|
||||
.TemporaryItems
|
||||
.Trashes
|
||||
.VolumeIcon.icns
|
||||
.com.apple.timemachine.donotpresent
|
||||
|
||||
# Directories potentially created on remote AFP share
|
||||
.AppleDB
|
||||
.AppleDesktop
|
||||
Network Trash Folder
|
||||
Temporary Items
|
||||
.apdisk
|
||||
|
||||
|
||||
|
||||
##########################################################
|
||||
# Specific to this module
|
||||
|
||||
# iml files are generated by intellij/gradle now
|
||||
**/*.iml
|
|
@ -0,0 +1,77 @@
|
|||
- JNA - Utilities for use within Java projects
|
||||
[The Apache Software License, Version 2.0]
|
||||
https://git.dorkbox.com/dorkbox/JNA
|
||||
Copyright 2023
|
||||
Dorkbox LLC
|
||||
|
||||
Extra license information
|
||||
- SLF4J - Simple facade or abstraction for various logging frameworks
|
||||
[MIT License]
|
||||
http://www.slf4j.org
|
||||
Copyright 2023
|
||||
QOS.ch
|
||||
|
||||
- Kotlin -
|
||||
[The Apache Software License, Version 2.0]
|
||||
https://github.com/JetBrains/kotlin
|
||||
Copyright 2020
|
||||
JetBrains s.r.o. and Kotlin Programming Language contributors
|
||||
Kotlin Compiler, Test Data+Libraries, and Tools repository contain third-party code, to which different licenses may apply
|
||||
See: https://github.com/JetBrains/kotlin/blob/master/license/README.md
|
||||
|
||||
- JNA - Simplified native library access for Java.
|
||||
[The Apache Software License, Version 2.0]
|
||||
https://github.com/twall/jna
|
||||
Copyright 2023
|
||||
Timothy Wall
|
||||
|
||||
- JNA-Platform - Mappings for a number of commonly used platform functions
|
||||
[The Apache Software License, Version 2.0]
|
||||
https://github.com/twall/jna
|
||||
Copyright 2023
|
||||
Timothy Wall
|
||||
|
||||
- OS - Information about the system, Java runtime, OS, Window Manager, and Desktop Environment.
|
||||
[The Apache Software License, Version 2.0]
|
||||
https://git.dorkbox.com/dorkbox/OS
|
||||
Copyright 2023
|
||||
Dorkbox LLC
|
||||
|
||||
Extra license information
|
||||
- Kotlin -
|
||||
[The Apache Software License, Version 2.0]
|
||||
https://github.com/JetBrains/kotlin
|
||||
Copyright 2020
|
||||
JetBrains s.r.o. and Kotlin Programming Language contributors
|
||||
Kotlin Compiler, Test Data+Libraries, and Tools repository contain third-party code, to which different licenses may apply
|
||||
See: https://github.com/JetBrains/kotlin/blob/master/license/README.md
|
||||
|
||||
- Updates - Software Update Management
|
||||
[The Apache Software License, Version 2.0]
|
||||
https://git.dorkbox.com/dorkbox/Updates
|
||||
Copyright 2021
|
||||
Dorkbox LLC
|
||||
|
||||
Extra license information
|
||||
- Kotlin -
|
||||
[The Apache Software License, Version 2.0]
|
||||
https://github.com/JetBrains/kotlin
|
||||
Copyright 2020
|
||||
JetBrains s.r.o. and Kotlin Programming Language contributors
|
||||
Kotlin Compiler, Test Data+Libraries, and Tools repository contain third-party code, to which different licenses may apply
|
||||
See: https://github.com/JetBrains/kotlin/blob/master/license/README.md
|
||||
|
||||
- Updates - Software Update Management
|
||||
[The Apache Software License, Version 2.0]
|
||||
https://git.dorkbox.com/dorkbox/Updates
|
||||
Copyright 2021
|
||||
Dorkbox LLC
|
||||
|
||||
Extra license information
|
||||
- Kotlin -
|
||||
[The Apache Software License, Version 2.0]
|
||||
https://github.com/JetBrains/kotlin
|
||||
Copyright 2020
|
||||
JetBrains s.r.o. and Kotlin Programming Language contributors
|
||||
Kotlin Compiler, Test Data+Libraries, and Tools repository contain third-party code, to which different licenses may apply
|
||||
See: https://github.com/JetBrains/kotlin/blob/master/license/README.md
|
|
@ -0,0 +1,218 @@
|
|||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
|
@ -0,0 +1,21 @@
|
|||
MIT License
|
||||
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
@ -0,0 +1,31 @@
|
|||
Dorkbox General Utilities
|
||||
|
||||
###### [![Dorkbox](https://badge.dorkbox.com/dorkbox.svg "Dorkbox")](https://git.dorkbox.com/dorkbox/JNA) [![Github](https://badge.dorkbox.com/github.svg "Github")](https://github.com/dorkbox/JNA) [![Gitlab](https://badge.dorkbox.com/gitlab.svg "Gitlab")](https://gitlab.com/dorkbox/JNA)
|
||||
|
||||
|
||||
Maven Info
|
||||
---------
|
||||
````
|
||||
<dependencies>
|
||||
...
|
||||
<dependency>
|
||||
<groupId>com.dorkbox</groupId>
|
||||
<artifactId>JNA</artifactId>
|
||||
<version>1.0</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
````
|
||||
|
||||
Gradle Info
|
||||
---------
|
||||
````
|
||||
dependencies {
|
||||
...
|
||||
compile "com.dorkbox:JNA:1.0"
|
||||
}
|
||||
````
|
||||
|
||||
|
||||
License
|
||||
---------
|
||||
This project is © 2023 dorkbox llc, and is distributed under the terms of the Apache v2.0 License. See file "LICENSE" for further references.
|
|
@ -0,0 +1,124 @@
|
|||
/*
|
||||
* Copyright 2023 dorkbox, llc
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import java.time.Instant
|
||||
|
||||
///////////////////////////////
|
||||
////// PUBLISH TO SONATYPE / MAVEN CENTRAL
|
||||
////// TESTING : (to local maven repo) <'publish and release' - 'publishToMavenLocal'>
|
||||
////// RELEASE : (to sonatype/maven central), <'publish and release' - 'publishToSonatypeAndRelease'>
|
||||
///////////////////////////////
|
||||
|
||||
gradle.startParameter.showStacktrace = ShowStacktrace.ALWAYS // always show the stacktrace!
|
||||
|
||||
plugins {
|
||||
id("com.dorkbox.GradleUtils") version "3.5.1"
|
||||
id("com.dorkbox.Licensing") version "2.17"
|
||||
id("com.dorkbox.VersionUpdate") version "2.5"
|
||||
id("com.dorkbox.GradlePublish") version "1.14"
|
||||
|
||||
kotlin("jvm") version "1.7.20"
|
||||
}
|
||||
|
||||
object Extras {
|
||||
// set for the project
|
||||
const val description = "Utilities for use within Java projects"
|
||||
const val group = "com.dorkbox"
|
||||
const val version = "1.0"
|
||||
|
||||
// set as project.ext
|
||||
const val name = "JNA"
|
||||
const val id = "JNA"
|
||||
const val vendor = "Dorkbox LLC"
|
||||
const val vendorUrl = "https://dorkbox.com"
|
||||
const val url = "https://git.dorkbox.com/dorkbox/JNA"
|
||||
|
||||
val buildDate = Instant.now().toString()
|
||||
}
|
||||
|
||||
///////////////////////////////
|
||||
///// assign 'Extras'
|
||||
///////////////////////////////
|
||||
GradleUtils.load("$projectDir/../../gradle.properties", Extras)
|
||||
GradleUtils.defaults()
|
||||
GradleUtils.compileConfiguration(JavaVersion.VERSION_1_8)
|
||||
GradleUtils.jpms(JavaVersion.VERSION_1_9)
|
||||
|
||||
licensing {
|
||||
license(License.APACHE_2) {
|
||||
description(Extras.description)
|
||||
author(Extras.vendor)
|
||||
url(Extras.url)
|
||||
}
|
||||
}
|
||||
|
||||
tasks.jar.get().apply {
|
||||
manifest {
|
||||
// https://docs.oracle.com/javase/tutorial/deployment/jar/packageman.html
|
||||
attributes["Name"] = Extras.name
|
||||
|
||||
attributes["Specification-Title"] = Extras.name
|
||||
attributes["Specification-Version"] = Extras.version
|
||||
attributes["Specification-Vendor"] = Extras.vendor
|
||||
|
||||
attributes["Implementation-Title"] = "${Extras.group}.${Extras.id}"
|
||||
attributes["Implementation-Version"] = Extras.buildDate
|
||||
attributes["Implementation-Vendor"] = Extras.vendor
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE: compileOnly is used because there are some classes/dependencies that ARE NOT necessary to be included, UNLESS the user
|
||||
// is actually using that part of the library. If this happens, they will (or should) already be using the dependency)
|
||||
dependencies {
|
||||
api("com.dorkbox:OS:1.6")
|
||||
api("com.dorkbox:Updates:1.1")
|
||||
|
||||
|
||||
val jnaVersion = "5.12.1"
|
||||
compileOnly("net.java.dev.jna:jna-jpms:$jnaVersion")
|
||||
compileOnly("net.java.dev.jna:jna-platform-jpms:$jnaVersion")
|
||||
|
||||
api("org.slf4j:slf4j-api:2.0.6")
|
||||
|
||||
|
||||
testImplementation("junit:junit:4.13.2")
|
||||
testImplementation("ch.qos.logback:logback-classic:1.4.5")
|
||||
}
|
||||
|
||||
|
||||
publishToSonatype {
|
||||
groupId = Extras.group
|
||||
artifactId = Extras.id
|
||||
version = Extras.version
|
||||
|
||||
name = Extras.name
|
||||
description = Extras.description
|
||||
url = Extras.url
|
||||
|
||||
vendor = Extras.vendor
|
||||
vendorUrl = Extras.vendorUrl
|
||||
|
||||
issueManagement {
|
||||
url = "${Extras.url}/issues"
|
||||
nickname = "Gitea Issues"
|
||||
}
|
||||
|
||||
developer {
|
||||
id = "dorkbox"
|
||||
name = Extras.vendor
|
||||
email = "email@dorkbox.com"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
# https://docs.gradle.org/current/userguide/build_environment.html#sec:gradle_configuration_properties
|
||||
org.gradle.jvmargs=-Dfile.encoding=UTF-8
|
||||
|
||||
#org.gradle.warning.mode=(all,fail,none,summary)
|
||||
org.gradle.warning.mode=all
|
||||
|
||||
org.gradle.daemon=false
|
||||
|
||||
#org.gradle.console=(auto,plain,rich,verbose)
|
||||
org.gradle.console=auto
|
||||
|
||||
#org.gradle.logging.level=(quiet,warn,lifecycle,info,debug)
|
||||
org.gradle.logging.level=lifecycle
|
Binary file not shown.
|
@ -0,0 +1,5 @@
|
|||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-all.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
|
@ -0,0 +1,240 @@
|
|||
#!/bin/sh
|
||||
|
||||
#
|
||||
# Copyright © 2015-2021 the original authors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
##############################################################################
|
||||
#
|
||||
# Gradle start up script for POSIX generated by Gradle.
|
||||
#
|
||||
# Important for running:
|
||||
#
|
||||
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
|
||||
# noncompliant, but you have some other compliant shell such as ksh or
|
||||
# bash, then to run this script, type that shell name before the whole
|
||||
# command line, like:
|
||||
#
|
||||
# ksh Gradle
|
||||
#
|
||||
# Busybox and similar reduced shells will NOT work, because this script
|
||||
# requires all of these POSIX shell features:
|
||||
# * functions;
|
||||
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
|
||||
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
|
||||
# * compound commands having a testable exit status, especially «case»;
|
||||
# * various built-in commands including «command», «set», and «ulimit».
|
||||
#
|
||||
# Important for patching:
|
||||
#
|
||||
# (2) This script targets any POSIX shell, so it avoids extensions provided
|
||||
# by Bash, Ksh, etc; in particular arrays are avoided.
|
||||
#
|
||||
# The "traditional" practice of packing multiple parameters into a
|
||||
# space-separated string is a well documented source of bugs and security
|
||||
# problems, so this is (mostly) avoided, by progressively accumulating
|
||||
# options in "$@", and eventually passing that to Java.
|
||||
#
|
||||
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
|
||||
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
|
||||
# see the in-line comments for details.
|
||||
#
|
||||
# There are tweaks for specific operating systems such as AIX, CygWin,
|
||||
# Darwin, MinGW, and NonStop.
|
||||
#
|
||||
# (3) This script is generated from the Groovy template
|
||||
# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||
# within the Gradle project.
|
||||
#
|
||||
# You can find Gradle at https://github.com/gradle/gradle/.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
# Attempt to set APP_HOME
|
||||
|
||||
# Resolve links: $0 may be a link
|
||||
app_path=$0
|
||||
|
||||
# Need this for daisy-chained symlinks.
|
||||
while
|
||||
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
|
||||
[ -h "$app_path" ]
|
||||
do
|
||||
ls=$( ls -ld "$app_path" )
|
||||
link=${ls#*' -> '}
|
||||
case $link in #(
|
||||
/*) app_path=$link ;; #(
|
||||
*) app_path=$APP_HOME$link ;;
|
||||
esac
|
||||
done
|
||||
|
||||
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
|
||||
|
||||
APP_NAME="Gradle"
|
||||
APP_BASE_NAME=${0##*/}
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD=maximum
|
||||
|
||||
warn () {
|
||||
echo "$*"
|
||||
} >&2
|
||||
|
||||
die () {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
} >&2
|
||||
|
||||
# OS specific support (must be 'true' or 'false').
|
||||
cygwin=false
|
||||
msys=false
|
||||
darwin=false
|
||||
nonstop=false
|
||||
case "$( uname )" in #(
|
||||
CYGWIN* ) cygwin=true ;; #(
|
||||
Darwin* ) darwin=true ;; #(
|
||||
MSYS* | MINGW* ) msys=true ;; #(
|
||||
NONSTOP* ) nonstop=true ;;
|
||||
esac
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD=$JAVA_HOME/jre/sh/java
|
||||
else
|
||||
JAVACMD=$JAVA_HOME/bin/java
|
||||
fi
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
else
|
||||
JAVACMD=java
|
||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
|
||||
case $MAX_FD in #(
|
||||
max*)
|
||||
MAX_FD=$( ulimit -H -n ) ||
|
||||
warn "Could not query maximum file descriptor limit"
|
||||
esac
|
||||
case $MAX_FD in #(
|
||||
'' | soft) :;; #(
|
||||
*)
|
||||
ulimit -n "$MAX_FD" ||
|
||||
warn "Could not set maximum file descriptor limit to $MAX_FD"
|
||||
esac
|
||||
fi
|
||||
|
||||
# Collect all arguments for the java command, stacking in reverse order:
|
||||
# * args from the command line
|
||||
# * the main class name
|
||||
# * -classpath
|
||||
# * -D...appname settings
|
||||
# * --module-path (only if needed)
|
||||
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
|
||||
|
||||
# For Cygwin or MSYS, switch paths to Windows format before running java
|
||||
if "$cygwin" || "$msys" ; then
|
||||
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
|
||||
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
|
||||
|
||||
JAVACMD=$( cygpath --unix "$JAVACMD" )
|
||||
|
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||
for arg do
|
||||
if
|
||||
case $arg in #(
|
||||
-*) false ;; # don't mess with options #(
|
||||
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
|
||||
[ -e "$t" ] ;; #(
|
||||
*) false ;;
|
||||
esac
|
||||
then
|
||||
arg=$( cygpath --path --ignore --mixed "$arg" )
|
||||
fi
|
||||
# Roll the args list around exactly as many times as the number of
|
||||
# args, so each arg winds up back in the position where it started, but
|
||||
# possibly modified.
|
||||
#
|
||||
# NB: a `for` loop captures its iteration list before it begins, so
|
||||
# changing the positional parameters here affects neither the number of
|
||||
# iterations, nor the values presented in `arg`.
|
||||
shift # remove old arg
|
||||
set -- "$@" "$arg" # push replacement arg
|
||||
done
|
||||
fi
|
||||
|
||||
# Collect all arguments for the java command;
|
||||
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
|
||||
# shell script including quotes and variable substitutions, so put them in
|
||||
# double quotes to make sure that they get re-expanded; and
|
||||
# * put everything else in single quotes, so that it's not re-expanded.
|
||||
|
||||
set -- \
|
||||
"-Dorg.gradle.appname=$APP_BASE_NAME" \
|
||||
-classpath "$CLASSPATH" \
|
||||
org.gradle.wrapper.GradleWrapperMain \
|
||||
"$@"
|
||||
|
||||
# Stop when "xargs" is not available.
|
||||
if ! command -v xargs >/dev/null 2>&1
|
||||
then
|
||||
die "xargs is not available"
|
||||
fi
|
||||
|
||||
# Use "xargs" to parse quoted args.
|
||||
#
|
||||
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
|
||||
#
|
||||
# In Bash we could simply go:
|
||||
#
|
||||
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
|
||||
# set -- "${ARGS[@]}" "$@"
|
||||
#
|
||||
# but POSIX shell has neither arrays nor command substitution, so instead we
|
||||
# post-process each arg (as a line of input to sed) to backslash-escape any
|
||||
# character that might be a shell metacharacter, then use eval to reverse
|
||||
# that process (while maintaining the separation between arguments), and wrap
|
||||
# the whole thing up as a single "set" statement.
|
||||
#
|
||||
# This will of course break if any of these variables contains a newline or
|
||||
# an unmatched quote.
|
||||
#
|
||||
|
||||
eval "set -- $(
|
||||
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
|
||||
xargs -n1 |
|
||||
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
|
||||
tr '\n' ' '
|
||||
)" '"$@"'
|
||||
|
||||
exec "$JAVACMD" "$@"
|
|
@ -0,0 +1,91 @@
|
|||
@rem
|
||||
@rem Copyright 2015 the original author or authors.
|
||||
@rem
|
||||
@rem Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@rem you may not use this file except in compliance with the License.
|
||||
@rem You may obtain a copy of the License at
|
||||
@rem
|
||||
@rem https://www.apache.org/licenses/LICENSE-2.0
|
||||
@rem
|
||||
@rem Unless required by applicable law or agreed to in writing, software
|
||||
@rem distributed under the License is distributed on an "AS IS" BASIS,
|
||||
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@rem See the License for the specific language governing permissions and
|
||||
@rem limitations under the License.
|
||||
@rem
|
||||
|
||||
@if "%DEBUG%"=="" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
@rem
|
||||
@rem ##########################################################################
|
||||
|
||||
@rem Set local scope for the variables with windows NT shell
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%"=="" set DIRNAME=.
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
|
||||
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if %ERRORLEVEL% equ 0 goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:findJavaFromJavaHome
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if %ERRORLEVEL% equ 0 goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
set EXIT_CODE=%ERRORLEVEL%
|
||||
if %EXIT_CODE% equ 0 set EXIT_CODE=1
|
||||
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
|
||||
exit /b %EXIT_CODE%
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
||||
:omega
|
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,19 @@
|
|||
///////////////////////////////
|
||||
// functions to make changing the maven POM easier
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
fun org.gradle.api.publish.maven.MavenPom.removeDependenciesByArtifactId(vararg names: String) {
|
||||
withXml {
|
||||
(asNode().get("dependencies") as List<groovy.util.Node>).forEach {deps ->
|
||||
(deps.children() as List<groovy.util.Node>).filter { it ->
|
||||
val text = (it.get("artifactId") as List<groovy.util.Node>).firstOrNull()?.text()
|
||||
if (text == null) {
|
||||
false
|
||||
} else {
|
||||
names.contains(text)
|
||||
}
|
||||
}.forEach { node->
|
||||
node.parent().remove(node)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
// WINDOWS XP
|
||||
// from: http://msdn.microsoft.com/en-us/library/e78byta0.aspx?cs-save-lang=1&cs-lang=csharp#code-snippet-2
|
||||
// certmgr /c /add TrustedCert.cer /s root
|
||||
//
|
||||
// more info from: http://tomfloor.wordpress.com/2012/11/09/command-line-certificate-installation-on-xp/
|
||||
// tool to download is from:
|
||||
// https://www.sslcertificaten.nl/download/Code_Signing_Tools/Authenticode_for_Internet_Explorer_toolkit
|
||||
|
||||
// install cert in windows: http://msdn.microsoft.com/en-us/library/e78byta0(v=vs.71).aspx (use certmgr.exe)
|
|
@ -0,0 +1,71 @@
|
|||
#!/bin/sh
|
||||
# This installs our cert into firefox, thunderbird, and chrome for linux
|
||||
# usage: incert.sh cert_name
|
||||
#
|
||||
|
||||
|
||||
# install for global OS purposes:
|
||||
# Given a CA ceritificate file 'foo.crt', follow these steps to install it on Ubuntu:
|
||||
#
|
||||
# Create a directory for extra CA certificates in /usr/share/ca-certificates
|
||||
#
|
||||
# sudo mkdir /usr/share/ca-certificates/extra
|
||||
# Copy the '.crt' file to the directory
|
||||
#
|
||||
# sudo cp foo.crt /usr/share/ca-certificates/extra/foo.crt
|
||||
# Add the '.crt' file's path relative to /usr/share/ca-certificates to /etc/ca-certificates.conf
|
||||
#
|
||||
# sudo dpkg-reconfigure ca-certificates
|
||||
# Update the installed CA's
|
||||
#
|
||||
# sudo update-ca-certificates
|
||||
|
||||
|
||||
|
||||
CERT_TOOL=""
|
||||
if [ "i686" = "$BUILDARCH" ]; then
|
||||
CERT_TOOL="./certutil_x86"
|
||||
else
|
||||
CERT_TOOL="./certutil_x64"
|
||||
fi
|
||||
|
||||
|
||||
CERT_FILE="certificate.crt"
|
||||
if [ -e "$1" ]; then
|
||||
CERT_FILE=$1
|
||||
fi
|
||||
|
||||
CERT_NAME="Dorkbox LLC CA"
|
||||
|
||||
# This installs for firefox
|
||||
if [ -e ~/.mozilla* ]; then
|
||||
for CERT_DB in $(find ~/.mozilla* -name "cert8.db")
|
||||
do
|
||||
CERT_DIR=$(dirname ${CERT_DB});
|
||||
#log "mozilla certificate" "install '${certificateName}' in ${CERT_DIR}"
|
||||
"${CERT_TOOL}" -d ${CERT_DIR} -A -n "${CERT_NAME}" -t "TCu,Cu,Cuw,Tuw" -i ${CERT_FILE}
|
||||
done
|
||||
fi
|
||||
|
||||
# This installs for thunderbird
|
||||
if [ -e ~/.thunderbird* ]; then
|
||||
for CERT_DB in $(find ~/.thunderbird* -name "cert8.db")
|
||||
do
|
||||
CERT_DIR=$(dirname ${CERT_DB});
|
||||
#log "mozilla certificate" "install '${certificateName}' in ${CERT_DIR}"
|
||||
"${CERT_TOOL}" -d ${CERT_DIR} -A -n "${CERT_NAME}" -t "TCu,Cu,Cuw,Tuw" -i ${CERT_FILE}
|
||||
done
|
||||
fi
|
||||
|
||||
|
||||
# This installs for chrome
|
||||
#NSS_DEFAULT_DB_TYPE="sql"
|
||||
if [ ! -e ~/.pki/nssdb ]; then
|
||||
echo "==========================="
|
||||
echo "No Database found. Creating one..."
|
||||
echo "==========================="
|
||||
"${CERT_TOOL}" -N -d sql:$HOME/.pki/nssdb
|
||||
fi
|
||||
"${CERT_TOOL}" -d sql:$HOME/.pki/nssdb -A -n "${CERT_NAME}" -t "TCu,Cu,Cuw,Tuw" -i ${CERT_FILE}
|
||||
"${CERT_TOOL}" -d ~/.pki/nssdb -L
|
||||
|
Binary file not shown.
|
@ -0,0 +1,15 @@
|
|||
/*
|
||||
* Copyright 2018 dorkbox, llc
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
|
@ -0,0 +1,9 @@
|
|||
package dorkbox.jna;
|
||||
|
||||
class ClassLoaderAccessory {
|
||||
// this class is to be overridden. This is on purpose, since this allows us to SKIP reflection when accessing classes, as we can
|
||||
// redefine this class at runtime (and at compile time, it is accessible)
|
||||
protected static Class findLoadedClass(ClassLoader classLoader, String className) {
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,222 @@
|
|||
/*
|
||||
* Copyright 2016 dorkbox, llc
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package dorkbox.jna;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import com.sun.jna.JNIEnv;
|
||||
import com.sun.jna.Library;
|
||||
import com.sun.jna.Native;
|
||||
import com.sun.jna.NativeLibrary;
|
||||
import com.sun.jna.win32.StdCallFunctionMapper;
|
||||
|
||||
import dorkbox.os.OS;
|
||||
|
||||
// http://hg.openjdk.java.net/jdk/jdk10/file/b09e56145e11/src/java.base/share/native/libjava/ClassLoader.c
|
||||
// http://hg.openjdk.java.net/jdk10/jdk10/jdk/file/777356696811/src/java.base/share/native/libjava/ClassLoader.c
|
||||
// http://hg.openjdk.java.net/jdk9/jdk9/jdk/file/65464a307408/src/java.base/share/native/libjava/ClassLoader.c
|
||||
// http://hg.openjdk.java.net/jdk8u/jdk8u/jdk/file/be698ac28848/src/share/native/java/lang/ClassLoader.c
|
||||
// http://hg.openjdk.java.net/jdk7/jdk7/hotspot/file/tip/src/share/vm/prims/jvm.cpp
|
||||
|
||||
// objdump -T <file> | grep foo
|
||||
// otool -tvV <file> | grep foo
|
||||
|
||||
/**
|
||||
* Gives us the ability to inject bytes into the "normal" classloader, or directly into java's bootstrap classloader.
|
||||
* <p>
|
||||
* When injecting into the bootstrap classloader, this COMPLETELY bypass all security checks, as it calls native methods directly via JNA.
|
||||
*/
|
||||
@SuppressWarnings({"WeakerAccess", "unchecked"})
|
||||
public class ClassUtils {
|
||||
private static final JVM libJvm;
|
||||
|
||||
// Note: this does not work in java8 x86 *on windows XP windows7, etc. It only works on x64
|
||||
@SuppressWarnings("UnusedReturnValue")
|
||||
public
|
||||
interface JVM extends com.sun.jna.Library {
|
||||
void JVM_DefineClass(JNIEnv env, String name, Object classLoader, byte[] buffer, int length, Object protectionDomain);
|
||||
}
|
||||
|
||||
private static final String libName;
|
||||
static {
|
||||
if (OS.INSTANCE.isMacOsX()) {
|
||||
if (OS.INSTANCE.getJavaVersion() < 7) {
|
||||
libName = "JavaVM";
|
||||
} else {
|
||||
String javaLocation = System.getProperty("java.home");
|
||||
|
||||
// have to explicitly specify the JVM library via full path
|
||||
// this is OK, because for java on MacOSX, this is the only location it can exist
|
||||
libName = javaLocation + "/lib/server/libjvm.dylib";
|
||||
}
|
||||
}
|
||||
else {
|
||||
libName = "jvm";
|
||||
}
|
||||
|
||||
|
||||
// function name is SLIGHTLY different on windows x32 java builds.
|
||||
// For actual name use: http://www.nirsoft.net/utils/dll_export_viewer.html
|
||||
//noinspection rawtypes
|
||||
Map options = new HashMap();
|
||||
options.put(Library.OPTION_ALLOW_OBJECTS, Boolean.TRUE);
|
||||
|
||||
if (OS.INSTANCE.isWindows() && OS.INSTANCE.is32bit()) {
|
||||
options.put(Library.OPTION_FUNCTION_MAPPER, new StdCallFunctionMapper() {
|
||||
@Override
|
||||
public
|
||||
String getFunctionName(NativeLibrary library, Method method) {
|
||||
String methodName = method.getName();
|
||||
if (methodName.equals("JVM_DefineClass")) {
|
||||
// specifically Oracle Java 32bit builds. Tested on XP and Win7
|
||||
return "_JVM_DefineClass@24";
|
||||
}
|
||||
return methodName;
|
||||
}
|
||||
});
|
||||
libJvm = Native.load(libName, JVM.class, options);
|
||||
} else {
|
||||
libJvm = Native.load(libName, JVM.class, options);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Defines a class in the current threads class-loader
|
||||
*
|
||||
* @param classBytes the bytes of the class to define
|
||||
*/
|
||||
public static
|
||||
void defineClass(final byte[] classBytes) throws Exception {
|
||||
java.lang.ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
|
||||
defineClass(classLoader, classBytes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Inject class bytes directly into the bootstrap classloader.
|
||||
* <p>
|
||||
* This is a VERY DANGEROUS method to use!
|
||||
*
|
||||
* @param classLoader the classLoader to use. null will use the BOOTSTRAP classloader
|
||||
* @param classBytes the bytes to inject
|
||||
*/
|
||||
@SuppressWarnings("RedundantThrows")
|
||||
public static
|
||||
void defineClass(java.lang.ClassLoader classLoader, byte[] classBytes) throws Exception {
|
||||
// inject into the FIRST JVM that are started by us (is USUALLY 1, but not always)
|
||||
libJvm.JVM_DefineClass(JNIEnv.CURRENT, null, classLoader, classBytes, classBytes.length, null);
|
||||
}
|
||||
|
||||
|
||||
private static
|
||||
AtomicBoolean loaded = new AtomicBoolean(false);
|
||||
|
||||
|
||||
/**
|
||||
* Finds the class in the specified classloader without the use of reflection
|
||||
*/
|
||||
public static Class<?> findLoadedClass(ClassLoader classLoader, String className) {
|
||||
// we rewrite the ClassFixer at runtime, as appropriate
|
||||
if (!loaded.getAndSet(true)) {
|
||||
// we do not have a dependency on javassist simply because we ALREADY know what the generated class bytes are (so there's no need)
|
||||
|
||||
|
||||
// try {
|
||||
// ClassPool pool = ClassPool.getDefault();
|
||||
// CtClass dynamicClass = pool.makeClass("java.lang.ClassLoaderAccessor");
|
||||
// CtMethod method = CtNewMethod.make("public static Class findLoadedClass(ClassLoader classLoader, String className) { " +
|
||||
// "return classLoader.findLoadedClass(className);" +
|
||||
// "}", dynamicClass);
|
||||
// dynamicClass.addMethod(method);
|
||||
// dynamicClass.setModifiers(dynamicClass.getModifiers() & ~Modifier.STATIC);
|
||||
//
|
||||
// final byte[] classLoaderAccessorBytes = dynamicClass.toBytecode();
|
||||
// Sys.printArray(classLoaderAccessorBytes);
|
||||
// } catch (Exception e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
//
|
||||
byte[] classLoaderAccessorBytes = {
|
||||
-54,-2,-70,-66,0,0,0,52,0,19,1,0,29,106,97,118,97,47,108,97,110,103,47,67,108,97,115,115,76,111,97,100,101,114,65,99,99,101,115,115,111,
|
||||
114,7,0,1,1,0,16,106,97,118,97,47,108,97,110,103,47,79,98,106,101,99,116,7,0,3,1,0,10,83,111,117,114,99,101,70,105,108,101,1,
|
||||
0,24,67,108,97,115,115,76,111,97,100,101,114,65,99,99,101,115,115,111,114,46,106,97,118,97,1,0,15,102,105,110,100,76,111,97,100,101,100,67,
|
||||
108,97,115,115,1,0,60,40,76,106,97,118,97,47,108,97,110,103,47,67,108,97,115,115,76,111,97,100,101,114,59,76,106,97,118,97,47,108,97,110,
|
||||
103,47,83,116,114,105,110,103,59,41,76,106,97,118,97,47,108,97,110,103,47,67,108,97,115,115,59,1,0,21,106,97,118,97,47,108,97,110,103,47,
|
||||
67,108,97,115,115,76,111,97,100,101,114,7,0,9,1,0,37,40,76,106,97,118,97,47,108,97,110,103,47,83,116,114,105,110,103,59,41,76,106,97,
|
||||
118,97,47,108,97,110,103,47,67,108,97,115,115,59,12,0,7,0,11,10,0,10,0,12,1,0,4,67,111,100,101,1,0,6,60,105,110,105,116,62,
|
||||
1,0,3,40,41,86,12,0,15,0,16,10,0,4,0,17,0,33,0,2,0,4,0,0,0,0,0,2,0,9,0,7,0,8,0,1,0,14,0,0,
|
||||
0,18,0,2,0,2,0,0,0,6,42,43,-74,0,13,-80,0,0,0,0,0,1,0,15,0,16,0,1,0,14,0,0,0,17,0,1,0,1,0,0,
|
||||
0,5,42,-73,0,18,-79,0,0,0,0,0,1,0,5,0,0,0,2,0,6};
|
||||
try {
|
||||
ClassUtils.defineClass(null, classLoaderAccessorBytes);
|
||||
} catch (Exception e) {
|
||||
// we are fully expecting this to be available. completely die if it's not!
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
|
||||
// try {
|
||||
// ClassPool pool = ClassPool.getDefault();
|
||||
// CtClass classFixer = pool.get("dorkbox.jna.ClassLoaderAccessory");
|
||||
// CtMethod ctMethod = classFixer.getDeclaredMethod("findLoadedClass");
|
||||
// ctMethod.setBody("{" +
|
||||
// "return java.lang.ClassLoaderAccessor.findLoadedClass($1, $2);" +
|
||||
// "}");
|
||||
//
|
||||
// // perform pre-verification for the modified method
|
||||
// ctMethod.getMethodInfo().rebuildStackMapForME(pool);
|
||||
//
|
||||
// final byte[] classFixerBytes = classFixer.toBytecode();
|
||||
// Sys.printArray(classFixerBytes);
|
||||
// } catch (Exception e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
byte[] classFixerBytes = {
|
||||
-54,-2,-70,-66,0,0,0,52,0,22,1,0,32,100,111,114,107,98,111,120,47,106,110,97,47,67,108,97,115,115,76,111,97,100,101,114,65,99,99,101,115,
|
||||
115,111,114,121,7,0,1,1,0,16,106,97,118,97,47,108,97,110,103,47,79,98,106,101,99,116,7,0,3,1,0,6,60,105,110,105,116,62,1,0,
|
||||
3,40,41,86,1,0,4,67,111,100,101,1,0,15,76,105,110,101,78,117,109,98,101,114,84,97,98,108,101,1,0,18,76,111,99,97,108,86,97,114,
|
||||
105,97,98,108,101,84,97,98,108,101,1,0,4,116,104,105,115,1,0,34,76,100,111,114,107,98,111,120,47,106,110,97,47,67,108,97,115,115,76,111,
|
||||
97,100,101,114,65,99,99,101,115,115,111,114,121,59,12,0,5,0,6,10,0,4,0,12,1,0,15,102,105,110,100,76,111,97,100,101,100,67,108,97,
|
||||
115,115,1,0,60,40,76,106,97,118,97,47,108,97,110,103,47,67,108,97,115,115,76,111,97,100,101,114,59,76,106,97,118,97,47,108,97,110,103,47,
|
||||
83,116,114,105,110,103,59,41,76,106,97,118,97,47,108,97,110,103,47,67,108,97,115,115,59,1,0,29,106,97,118,97,47,108,97,110,103,47,67,108,
|
||||
97,115,115,76,111,97,100,101,114,65,99,99,101,115,115,111,114,7,0,16,12,0,14,0,15,10,0,17,0,18,1,0,10,83,111,117,114,99,101,70,
|
||||
105,108,101,1,0,25,67,108,97,115,115,76,111,97,100,101,114,65,99,99,101,115,115,111,114,121,46,106,97,118,97,0,32,0,2,0,4,0,0,0,
|
||||
0,0,2,0,0,0,5,0,6,0,1,0,7,0,0,0,47,0,1,0,1,0,0,0,5,42,-73,0,13,-79,0,0,0,2,0,8,0,0,0,6,
|
||||
0,1,0,0,0,3,0,9,0,0,0,12,0,1,0,0,0,5,0,10,0,11,0,0,0,12,0,14,0,15,0,1,0,7,0,0,0,18,0,2,
|
||||
0,2,0,0,0,6,42,43,-72,0,19,-80,0,0,0,0,0,1,0,20,0,0,0,2,0,21};
|
||||
|
||||
try {
|
||||
// specifically not in the bootstrap classloader -- but instead in the classloader initially searched (which might be the wrong one)
|
||||
ClassUtils.defineClass(classLoader, classFixerBytes);
|
||||
} catch (Exception e) {
|
||||
// we are fully expecting this to be available. completely die if it's not!
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
return ClassLoaderAccessory.findLoadedClass(classLoader, className);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the specified classloader has the class loaded or not, without the use of reflection
|
||||
*/
|
||||
public static boolean isClassLoaded(ClassLoader classLoader, String className) {
|
||||
return null != findLoadedClass(classLoader, className);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
* Copyright 2016 dorkbox, llc
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package dorkbox.jna;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import com.sun.jna.Library;
|
||||
import com.sun.jna.Native;
|
||||
import com.sun.jna.NativeLibrary;
|
||||
import com.sun.jna.win32.W32APIOptions;
|
||||
|
||||
import dorkbox.os.OS;
|
||||
|
||||
/**
|
||||
* Helper method to get the library info from JNA when registering via direct map
|
||||
*/
|
||||
public
|
||||
class JNA {
|
||||
|
||||
/**
|
||||
* Gets the version number.
|
||||
*/
|
||||
public static
|
||||
String getVersion() {
|
||||
return "1.0";
|
||||
}
|
||||
|
||||
static {
|
||||
// Add this project to the updates system, which verifies this class + UUID + version information
|
||||
dorkbox.updates.Updates.INSTANCE.add(JNA.class, "b416694a22ed4a1d9e612a1e9b6c76cf", getVersion());
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static
|
||||
NativeLibrary register(final String libraryName, final Class<?> clazz) throws IllegalArgumentException {
|
||||
final Map<String, Object> options = new HashMap<String, Object>();
|
||||
options.put(Library.OPTION_CLASSLOADER, clazz.getClassLoader());
|
||||
|
||||
if (OS.INSTANCE.isWindows()) {
|
||||
Set<Map.Entry<String, Object>> entries = W32APIOptions.DEFAULT_OPTIONS.entrySet();
|
||||
for (Map.Entry<String, Object> entry : entries) {
|
||||
options.put(entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
final NativeLibrary library = NativeLibrary.getInstance(libraryName, options);
|
||||
if (library == null) {
|
||||
throw new IllegalArgumentException(libraryName + " doesn't exist or cannot be loaded.");
|
||||
}
|
||||
|
||||
Native.register(clazz, library);
|
||||
return library;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
package dorkbox.jna
|
||||
|
||||
import java.io.File
|
||||
import java.util.concurrent.*
|
||||
|
||||
internal object KotlinUtils {
|
||||
/**
|
||||
* Reads the contents of the supplied input stream into a list of lines.
|
||||
*
|
||||
* @return Always returns a list, even if the file does not exist, or there are errors reading it.
|
||||
*/
|
||||
fun readLines(file: File): List<String> {
|
||||
return file.readLines()
|
||||
}
|
||||
|
||||
fun toInteger(string: String?): Int? {
|
||||
return string?.toIntOrNull()
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the given command and returns its output.
|
||||
*
|
||||
* This is based on an aggregate of the answers provided here: [https://stackoverflow.com/questions/35421699/how-to-invoke-external-command-from-within-kotlin-code]
|
||||
*/
|
||||
fun execute(vararg args: String): String {
|
||||
return ProcessBuilder(args.toList())
|
||||
.redirectOutput(ProcessBuilder.Redirect.PIPE)
|
||||
.redirectError(ProcessBuilder.Redirect.PIPE)
|
||||
.start()
|
||||
.apply { waitFor(60, TimeUnit.SECONDS) }
|
||||
.inputStream.bufferedReader().readText().trim()
|
||||
}
|
||||
}
|
|
@ -0,0 +1,187 @@
|
|||
/*
|
||||
* Copyright 2015 dorkbox, llc
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package dorkbox.jna.linux;
|
||||
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.sun.jna.Pointer;
|
||||
|
||||
import dorkbox.jna.JNA;
|
||||
import dorkbox.jna.linux.structs.AppIndicatorInstanceStruct;
|
||||
import dorkbox.os.OS;
|
||||
|
||||
/**
|
||||
* bindings for libappindicator
|
||||
*
|
||||
* Direct-mapping, See: https://github.com/java-native-access/jna/blob/master/www/DirectMapping.md
|
||||
*/
|
||||
@SuppressWarnings({"Duplicates", "SameParameterValue", "DanglingJavadoc"})
|
||||
public
|
||||
class AppIndicator {
|
||||
public static final boolean isLoaded;
|
||||
|
||||
/**
|
||||
* Loader for AppIndicator, because it is absolutely mindboggling how those whom maintain the standard, can't agree to what that
|
||||
* standard library naming convention or features/API set is. We just try until we find one that works, and are able to map the
|
||||
* symbols we need. There are bash commands that will tell us the linked library name, however - I'd rather not run bash commands
|
||||
* to determine this.
|
||||
*
|
||||
* This is so hacky it makes me sick.
|
||||
*/
|
||||
static {
|
||||
boolean _isLoaded = false;
|
||||
|
||||
boolean shouldLoadAppIndicator = !(OS.INSTANCE.isWindows() || OS.INSTANCE.isMacOsX());
|
||||
if (!shouldLoadAppIndicator) {
|
||||
_isLoaded = true;
|
||||
}
|
||||
|
||||
// GTK must be loaded!!
|
||||
if (!Gtk.isLoaded) {
|
||||
shouldLoadAppIndicator = false;
|
||||
_isLoaded = true;
|
||||
}
|
||||
|
||||
// objdump -T /usr/lib/x86_64-linux-gnu/libappindicator.so.1 | grep foo
|
||||
// objdump -T /usr/lib/x86_64-linux-gnu/libappindicator3.so.1 | grep foo
|
||||
|
||||
// NOTE:
|
||||
// ALSO WHAT VERSION OF GTK to use? appindiactor1 -> GTK2, appindicator3 -> GTK3.
|
||||
// appindiactor1 is GKT2 only (can't use GTK3 bindings with it)
|
||||
// appindicator3 doesn't support menu icons via GTK2!!
|
||||
|
||||
// appindicator3 doesn't support menu icons via GTK2!! *but it can work* -- we ignore this use-case, because it's so buggy
|
||||
// We want to load the matching appindicator library to the loaded GTK version
|
||||
|
||||
String[] GTK2 = new String[] {"appindicator", "appindicator1", "appindicator-gtk"};
|
||||
String[] GTK3 = new String[] {"appindicator3", "appindicator3-1", "appindicator-gtk3", "appindicator-gtk3-1"};
|
||||
|
||||
// NOTE: appindicator1 -> GTk2, appindicator3 -> GTK3.
|
||||
// Note: appindicator-gtk3 is Fedora...
|
||||
|
||||
if (Gtk.isGtk2) {
|
||||
for (String libraryName : GTK2) {
|
||||
if (!_isLoaded) {
|
||||
try {
|
||||
JNA.register(libraryName, AppIndicator.class);
|
||||
_isLoaded = true;
|
||||
if (GtkEventDispatch.DEBUG) {
|
||||
LoggerFactory.getLogger(AppIndicator.class).debug("Loaded GTK2 library name '{}'.", libraryName);
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
if (GtkEventDispatch.DEBUG) {
|
||||
LoggerFactory.getLogger(AppIndicator.class).debug("Error loading GTK2 library name '{}'.", libraryName, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (Gtk.isGtk3) {
|
||||
for (String libraryName : GTK3) {
|
||||
if (!_isLoaded) {
|
||||
try {
|
||||
JNA.register(libraryName, AppIndicator.class);
|
||||
_isLoaded = true;
|
||||
if (GtkEventDispatch.DEBUG) {
|
||||
LoggerFactory.getLogger(AppIndicator.class).debug("Loaded GTK3 library name '{}'.", libraryName);
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
if (GtkEventDispatch.DEBUG) {
|
||||
LoggerFactory.getLogger(AppIndicator.class).debug("Error loading GTK3 library name '{}'.", libraryName, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// We can fall back to GtkStatusIndicator or Swing if this cannot load
|
||||
isLoaded = shouldLoadAppIndicator && _isLoaded;
|
||||
}
|
||||
|
||||
// Note: AppIndicators DO NOT support tooltips, as per mark shuttleworth. Rather stupid IMHO.
|
||||
// See: https://bugs.launchpad.net/indicator-application/+bug/527458/comments/12
|
||||
|
||||
|
||||
public static
|
||||
String getInstallString(boolean isGtk2) {
|
||||
// ARCH
|
||||
// requires the install of libappindicator which is GTK2 (as of 25DEC2016)
|
||||
// requires the install of libappindicator3 which is GTK3 (as of 25DEC2016)
|
||||
|
||||
// FEDORA
|
||||
// libappindicator-gtk
|
||||
// libappindicator-gtk3
|
||||
|
||||
// ARCH
|
||||
// libappindicator-gtk2
|
||||
// libappindicator-gtk3
|
||||
|
||||
// Debian based
|
||||
// libappindicator
|
||||
// libappindicator3 (or 3-1)
|
||||
|
||||
|
||||
if (isGtk2) {
|
||||
if (OS.Linux.INSTANCE.isDebian()) {
|
||||
// debian is slightly different
|
||||
return "libappindicator1";
|
||||
}
|
||||
else if (OS.Linux.INSTANCE.isFedora()) {
|
||||
return "libappindicator-gtk";
|
||||
}
|
||||
else if (OS.Linux.INSTANCE.isArch()) {
|
||||
return "libappindicator-gtk2";
|
||||
}
|
||||
else {
|
||||
return "libappindicator";
|
||||
}
|
||||
} else {
|
||||
if (OS.Linux.INSTANCE.isDebian()) {
|
||||
// debian is slightly different
|
||||
return "libappindicator3-1";
|
||||
}
|
||||
else if (OS.Linux.INSTANCE.isFedora()) {
|
||||
return "libappindicator-gtk3";
|
||||
}
|
||||
else if (OS.Linux.INSTANCE.isArch()) {
|
||||
return "libappindicator-gtk3";
|
||||
}
|
||||
else {
|
||||
return "libappindicator3";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static final int CATEGORY_APPLICATION_STATUS = 0;
|
||||
// public static final int CATEGORY_COMMUNICATIONS = 1;
|
||||
// public static final int CATEGORY_SYSTEM_SERVICES = 2;
|
||||
// public static final int CATEGORY_HARDWARE = 3;
|
||||
// public static final int CATEGORY_OTHER = 4;
|
||||
|
||||
public static final int STATUS_PASSIVE = 0;
|
||||
public static final int STATUS_ACTIVE = 1;
|
||||
// public static final int STATUS_ATTENTION = 2;
|
||||
|
||||
|
||||
public static native
|
||||
AppIndicatorInstanceStruct app_indicator_new(String id, String icon_name, int category);
|
||||
|
||||
public static native void app_indicator_set_title(Pointer indicator, String title);
|
||||
public static native void app_indicator_set_status(Pointer indicator, int status);
|
||||
public static native void app_indicator_set_menu(Pointer indicator, Pointer menu);
|
||||
public static native void app_indicator_set_icon(Pointer indicator, String icon_name);
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* Copyright 2010 dorkbox, llc
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package dorkbox.jna.linux;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import com.sun.jna.Native;
|
||||
import com.sun.jna.ptr.IntByReference;
|
||||
|
||||
import dorkbox.jna.linux.structs.Termios;
|
||||
|
||||
@SuppressWarnings("ALL")
|
||||
public
|
||||
class CLibraryPosix {
|
||||
static {
|
||||
Native.register("c");
|
||||
}
|
||||
|
||||
// MAGIC!
|
||||
public static final int TIOCGWINSZ = System.getProperty("os.name").equalsIgnoreCase("linux") ? 0x5413 : 1074295912;
|
||||
|
||||
|
||||
public static native
|
||||
int isatty(int fd);
|
||||
|
||||
public static native
|
||||
int read(int fd, IntByReference c, int count);
|
||||
|
||||
/**
|
||||
* Original signature : <code>int ioctl(int, int, char*)</code><br>
|
||||
*/
|
||||
public static native
|
||||
int ioctl(int d, int request, ByteBuffer data);
|
||||
|
||||
/**
|
||||
* Put the state of FD into *TERMIOS_P.<br>
|
||||
* <p>
|
||||
* Original signature : <code>int tcgetattr(int, char*)</code><br>
|
||||
*/
|
||||
public static native
|
||||
int tcgetattr(int fd, Termios termios_p);
|
||||
|
||||
/**
|
||||
* Set the state of FD to *TERMIOS_P.<br>
|
||||
* <p>
|
||||
* Values for OPTIONAL_ACTIONS (TCSA*) are in <bits/termios.h>.<br>
|
||||
* <p>
|
||||
* Original signature : <code>int tcsetattr(int, int, char*)</code><br>
|
||||
*/
|
||||
public static native
|
||||
int tcsetattr(int fd, int optional_actions, Termios termios_p);
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* Copyright 2015 dorkbox, llc
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package dorkbox.jna.linux;
|
||||
|
||||
import com.sun.jna.Callback;
|
||||
import com.sun.jna.Pointer;
|
||||
|
||||
public
|
||||
interface FuncCallback extends Callback {
|
||||
/**
|
||||
* @return Gtk.FALSE if it will be automatically removed from the stack once it's handled
|
||||
*/
|
||||
int callback(Pointer data);
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* Copyright 2015 dorkbox, llc
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package dorkbox.jna.linux;
|
||||
|
||||
import com.sun.jna.Callback;
|
||||
import com.sun.jna.Pointer;
|
||||
|
||||
public
|
||||
interface GCallback extends Callback {
|
||||
/**
|
||||
* @return Gtk.TRUE if we handled this event
|
||||
*/
|
||||
int callback(Pointer instance, Pointer data);
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* Copyright 2015 dorkbox, llc
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package dorkbox.jna.linux;
|
||||
|
||||
import com.sun.jna.Callback;
|
||||
import com.sun.jna.Pointer;
|
||||
|
||||
import dorkbox.jna.linux.structs.GdkEventButton;
|
||||
|
||||
public
|
||||
interface GEventCallback extends Callback {
|
||||
void callback(Pointer instance, GdkEventButton event);
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* Copyright 2017 dorkbox, llc
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package dorkbox.jna.linux;
|
||||
|
||||
import com.sun.jna.Pointer;
|
||||
|
||||
public
|
||||
class GMainContext extends GObjectType {
|
||||
public
|
||||
GMainContext() {
|
||||
}
|
||||
|
||||
public
|
||||
GMainContext(Pointer p) {
|
||||
super(p);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* Copyright 2017 dorkbox, llc
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package dorkbox.jna.linux;
|
||||
|
||||
import com.sun.jna.Pointer;
|
||||
|
||||
public
|
||||
class GMainLoop extends GObjectType {
|
||||
public
|
||||
GMainLoop() {
|
||||
}
|
||||
|
||||
public
|
||||
GMainLoop(Pointer p) {
|
||||
super(p);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
* Copyright 2015 dorkbox, llc
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package dorkbox.jna.linux;
|
||||
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.sun.jna.Callback;
|
||||
import com.sun.jna.NativeLibrary;
|
||||
import com.sun.jna.Pointer;
|
||||
|
||||
import dorkbox.jna.JNA;
|
||||
|
||||
/**
|
||||
* bindings for libgobject-2.0
|
||||
*
|
||||
* Direct-mapping, See: https://github.com/java-native-access/jna/blob/master/www/DirectMapping.md
|
||||
*/
|
||||
public
|
||||
class GObject {
|
||||
|
||||
static {
|
||||
try {
|
||||
NativeLibrary library = JNA.register("gobject-2.0", GObject.class);
|
||||
if (library == null) {
|
||||
LoggerFactory.getLogger(GObject.class).error("Error loading GObject library, it failed to load.");
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
LoggerFactory.getLogger(GObject.class).error("Error loading GObject library, it failed to load {}", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
// objdump -T /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0 | grep block
|
||||
|
||||
public static native void g_object_ref(Pointer object);
|
||||
public static native void g_object_unref(Pointer object);
|
||||
|
||||
public static native void g_object_force_floating(Pointer object);
|
||||
public static native void g_object_ref_sink(Pointer object);
|
||||
|
||||
// note: the return type here MUST be long to avoid issues on freeBSD. NativeLong (previously used) worked on everything except BSD.
|
||||
public static native long g_signal_connect_object(Pointer instance, String detailed_signal, Callback c_handler, Pointer object, int connect_flags);
|
||||
|
||||
public static native void g_signal_handler_block(Pointer instance, long handlerId);
|
||||
public static native void g_signal_handler_unblock(Pointer instance, long handlerId);
|
||||
|
||||
public static native void g_object_get(Pointer instance, String property_name, Pointer value, Pointer terminator);
|
||||
|
||||
|
||||
|
||||
// Types are here https://developer.gnome.org/gobject/stable/gobject-Type-Information.html
|
||||
public static native void g_value_init(Pointer gvalue, double type);
|
||||
|
||||
/**
|
||||
* Clears the current value in value (if any) and "unsets" the type, this releases all resources associated with this GValue.
|
||||
* An unset value is the same as an uninitialized (zero-filled) GValue structure.
|
||||
*/
|
||||
public static native void g_value_unset(Pointer gvalue);
|
||||
|
||||
public static native String g_value_get_string(Pointer gvalue);
|
||||
public static native int g_value_get_int(Pointer gvalue);
|
||||
|
||||
public static native Pointer g_type_class_ref(Pointer widgetType);
|
||||
public static native void g_type_class_unref(Pointer widgetClass);
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* Copyright 2017 dorkbox, llc
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package dorkbox.jna.linux;
|
||||
|
||||
import com.sun.jna.Pointer;
|
||||
import com.sun.jna.PointerType;
|
||||
|
||||
public
|
||||
class GObjectType extends PointerType {
|
||||
public
|
||||
GObjectType() {
|
||||
}
|
||||
|
||||
public
|
||||
GObjectType(Pointer p) {
|
||||
super(p);
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
protected
|
||||
void finalize() throws Throwable {
|
||||
super.finalize();
|
||||
}
|
||||
|
||||
public
|
||||
void ref() {
|
||||
GObject.g_object_ref(getPointer());
|
||||
}
|
||||
|
||||
public
|
||||
void unref() {
|
||||
GObject.g_object_unref(getPointer());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
* Copyright 2017 dorkbox, llc
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package dorkbox.jna.linux;
|
||||
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.sun.jna.Callback;
|
||||
import com.sun.jna.NativeLibrary;
|
||||
import com.sun.jna.Pointer;
|
||||
|
||||
import dorkbox.jna.JNA;
|
||||
|
||||
/**
|
||||
* bindings for glib-2.0
|
||||
*
|
||||
* Direct-mapping, See: https://github.com/java-native-access/jna/blob/master/www/DirectMapping.md
|
||||
*/
|
||||
public
|
||||
class Glib {
|
||||
static {
|
||||
try {
|
||||
NativeLibrary library = JNA.register("glib-2.0", Glib.class);
|
||||
if (library == null) {
|
||||
LoggerFactory.getLogger(Glib.class).error("Error loading Glib library, it failed to load.");
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
LoggerFactory.getLogger(Glib.class).error("Error loading Glib library, it failed to load {}", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public interface GLogLevelFlags {
|
||||
public static final int RECURSION = 1 << 0;
|
||||
public static final int FATAL = 1 << 1;
|
||||
/* GLib log levels */
|
||||
public static final int ERROR = 1 << 2; /* always fatal */
|
||||
public static final int CRITICAL = 1 << 3;
|
||||
public static final int WARNING = 1 << 4;
|
||||
public static final int MESSAGE = 1 << 5;
|
||||
public static final int INFO = 1 << 6;
|
||||
public static final int DEBUG = 1 << 7;
|
||||
public static final int MASK = ~(RECURSION | FATAL);
|
||||
}
|
||||
|
||||
public interface GLogFunc extends Callback {
|
||||
void callback (String log_domain, int log_level, String message, Pointer data);
|
||||
}
|
||||
|
||||
public static final Glib.GLogFunc nullLogFunc = new Glib.GLogFunc() {
|
||||
@Override
|
||||
public
|
||||
void callback(final String log_domain, final int log_level, final String message, final Pointer data) {
|
||||
// do nothing
|
||||
}
|
||||
};
|
||||
|
||||
public static native int g_log_set_handler(String log_domain, int levels, GLogFunc handler, Pointer user_data);
|
||||
public static native void g_log_default_handler (String log_domain, int log_level, String message, Pointer unused_data);
|
||||
public static native GLogFunc g_log_set_default_handler(GLogFunc log_func, Pointer user_data);
|
||||
public static native void g_log_remove_handler (String log_domain, int handler_id);
|
||||
}
|
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
* Copyright 2017 dorkbox, llc
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package dorkbox.jna.linux;
|
||||
|
||||
import com.sun.jna.NativeLibrary;
|
||||
import com.sun.jna.Pointer;
|
||||
|
||||
import dorkbox.jna.JNA;
|
||||
|
||||
/**
|
||||
* bindings for gnome
|
||||
* <p>
|
||||
* Direct-mapping, See: https://github.com/java-native-access/jna/blob/master/www/DirectMapping.md
|
||||
* <p>
|
||||
* https://github.com/GNOME/libgnome/blob/master/libgnome/gnome-url.c
|
||||
*
|
||||
* NOTE: This is used to open URL/file/email/etc from java. In different places, they recommend using gtk_show_uri() -- we support that,
|
||||
* NOTE: HOWEVER there are problems where GTK warnings/errors will STILL SHOW on the console for whatever target application is opened,
|
||||
* NOTE: and because of these errors, it looks like crap. gnome_vfs_url_show_with_env() solves this problem.
|
||||
*/
|
||||
public
|
||||
class GnomeVFS {
|
||||
public final static boolean isInited;
|
||||
|
||||
static {
|
||||
boolean init = false;
|
||||
try {
|
||||
NativeLibrary library = JNA.register("libgnomevfs-2", GnomeVFS.class);
|
||||
if (library == null) {
|
||||
// try with no version
|
||||
library = JNA.register("libgnomevfs", GnomeVFS.class);
|
||||
}
|
||||
if (library == null) {
|
||||
// try v3 (maybe this happened? Not likely, but who knows)
|
||||
library = JNA.register("libgnomevfs-3", GnomeVFS.class);
|
||||
}
|
||||
|
||||
//noinspection StatementWithEmptyBody
|
||||
if (library == null) {
|
||||
// not loading :/
|
||||
// fail silently, because we only use this for loading URLs, and have fallbacks in place
|
||||
// LoggerFactory.getLogger(GnomeVFS.class).error("Error loading GnomeVFS library, it failed to load.");
|
||||
} else {
|
||||
// must call call gnome_vfs_init()
|
||||
GnomeVFS.gnome_vfs_init();
|
||||
init = true;
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
// fail silently, because we only use this for loading URLs, and have fallbacks in place
|
||||
// LoggerFactory.getLogger(GnomeVFS.class).error("Error loading GnomeVFS library, it failed to load {}", e.getMessage());
|
||||
}
|
||||
|
||||
isInited = init;
|
||||
}
|
||||
|
||||
public static native
|
||||
void gnome_vfs_init();
|
||||
|
||||
/**
|
||||
* Open a URL or path to display using the default/registered handlers.
|
||||
*
|
||||
* @param url The url or path to display. The path can be relative to the current working
|
||||
* directory or the user's home directory. This function will convert it into a fully
|
||||
* qualified url using the gnome_url_get_from_input function.
|
||||
*
|
||||
* @return 0 if successful, non-0 if there were issues.
|
||||
*/
|
||||
public static native
|
||||
int gnome_vfs_url_show_with_env(String url, Pointer shouldbeNull);
|
||||
}
|
|
@ -0,0 +1,416 @@
|
|||
/*
|
||||
* Copyright 2015 dorkbox, llc
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package dorkbox.jna.linux;
|
||||
|
||||
import com.sun.jna.Function;
|
||||
import com.sun.jna.Pointer;
|
||||
|
||||
import dorkbox.jna.linux.structs.GtkStyle;
|
||||
|
||||
/**
|
||||
* Bindings for GTK+ 2. Bindings that are exclusively for GTK+ 3 are in that respective class
|
||||
* <p>
|
||||
* Direct-mapping, See: https://github.com/java-native-access/jna/blob/master/www/DirectMapping.md
|
||||
*/
|
||||
@SuppressWarnings({"Duplicates", "SameParameterValue", "DeprecatedIsStillUsed", "WeakerAccess", "UnusedReturnValue"})
|
||||
public
|
||||
interface Gtk {
|
||||
// objdump -T /usr/lib/x86_64-linux-gnu/libgtk-x11-2.0.so.0 | grep gtk
|
||||
// objdump -T /usr/lib/x86_64-linux-gnu/libgtk-3.so.0 | grep gtk
|
||||
// objdump -T /usr/local/lib/libgtk-3.so.0 | grep gtk
|
||||
|
||||
// For funsies to look at, SyncThing did a LOT of work on compatibility in python (unfortunate for us, but interesting).
|
||||
// https://github.com/syncthing/syncthing-gtk/blob/b7a3bc00e3bb6d62365ae62b5395370f3dcc7f55/syncthing_gtk/statusicon.py
|
||||
|
||||
int FALSE = 0;
|
||||
int TRUE = 1;
|
||||
|
||||
// use GtkCheck for a safe accessor of these
|
||||
int MAJOR = GtkLoader.MAJOR;
|
||||
int MINOR = GtkLoader.MINOR;
|
||||
int MICRO = GtkLoader.MICRO;
|
||||
|
||||
// make specific versions of GTK2 vs GTK3 APIs
|
||||
// ALSO, GTK must be loaded via .init()
|
||||
Gtk Gtk2 = GtkLoader.isGtk2 ? new Gtk2() : new Gtk3();
|
||||
dorkbox.jna.linux.Gtk3 Gtk3 = GtkLoader.isGtk2 ? null : (Gtk3) Gtk2;
|
||||
|
||||
// use GtkCheck for a safe accessor of these
|
||||
boolean isGtk2 = GtkLoader.isGtk2;
|
||||
boolean isGtk3 = GtkLoader.isGtk3;
|
||||
boolean isLoaded = GtkLoader.isLoaded;
|
||||
|
||||
boolean alreadyRunningGTK = GtkLoader.alreadyRunningGTK;
|
||||
|
||||
Function gtk_status_icon_position_menu = GtkLoader.gtk_status_icon_position_menu;
|
||||
|
||||
/**
|
||||
* This would NORMALLY have a 2nd argument that is a String[] -- however JNA direct-mapping DOES NOT support this. We are lucky
|
||||
* enough that we just pass 'null' as the second argument, therefore, we don't have to define that parameter here.
|
||||
*
|
||||
* This does the same thing as gtk_init(), but without a hard quit
|
||||
*/
|
||||
boolean gtk_init_check(int argc);
|
||||
|
||||
/**
|
||||
* Creates a new GMainLoop structure.
|
||||
*/
|
||||
GMainLoop g_main_loop_new(Pointer context, boolean is_running);
|
||||
|
||||
/**
|
||||
* Runs a main loop until g_main_loop_quit() is called on the loop. If this is called for the thread of the loop's GMainContext,
|
||||
* it will process events from the loop, otherwise it will simply wait.
|
||||
*/
|
||||
void g_main_loop_run(GMainLoop loop);
|
||||
|
||||
/**
|
||||
* Stops a GMainLoop from running. Any calls to g_main_loop_run() for the loop will return.
|
||||
* Note that sources that have already been dispatched when g_main_loop_quit() is called will still be executed.
|
||||
*/
|
||||
void g_main_loop_quit(GMainLoop loop);
|
||||
|
||||
/**
|
||||
* Returns the GMainContext of loop .
|
||||
*/
|
||||
GMainContext g_main_loop_get_context(GMainLoop loop);
|
||||
|
||||
/**
|
||||
* Invokes a function in such a way that context is owned during the invocation of function .
|
||||
*/
|
||||
void g_main_context_invoke(GMainContext c, FuncCallback func, Pointer data);
|
||||
|
||||
/**
|
||||
* Creates a new GtkMenu
|
||||
*/
|
||||
Pointer gtk_menu_new();
|
||||
|
||||
/**
|
||||
* Sets or replaces the menu item’s submenu, or removes it when a NULL submenu is passed.
|
||||
*/
|
||||
void gtk_menu_item_set_submenu(Pointer menuEntry, Pointer menu);
|
||||
|
||||
/**
|
||||
* Creates a new GtkSeparatorMenuItem.
|
||||
*/
|
||||
Pointer gtk_separator_menu_item_new();
|
||||
|
||||
/**
|
||||
* Creates a new GtkImage displaying the file filename . If the file isn’t found or can’t be loaded, the resulting GtkImage will
|
||||
* display a "broken image" icon. This function never returns NULL, it always returns a valid GtkImage widget.
|
||||
* <p>
|
||||
* If the file contains an animation, the image will contain an animation.
|
||||
*/
|
||||
Pointer gtk_image_new_from_file(String iconPath);
|
||||
|
||||
/**
|
||||
* Sets the active state of the menu item’s check box.
|
||||
*/
|
||||
void gtk_check_menu_item_set_active(Pointer check_menu_item, boolean isChecked);
|
||||
|
||||
/**
|
||||
* Creates a new GtkImageMenuItem containing a label. The label will be created using gtk_label_new_with_mnemonic(), so underscores
|
||||
* in label indicate the mnemonic for the menu item.
|
||||
* <p>
|
||||
* uses '_' to define which key is the mnemonic
|
||||
* <p>
|
||||
* gtk_image_menu_item_new_with_mnemonic has been deprecated since version 3.10 and should not be used in newly-written code.
|
||||
* NOTE: Use gtk_menu_item_new_with_mnemonic() instead.
|
||||
*/
|
||||
Pointer gtk_image_menu_item_new_with_mnemonic(String label);
|
||||
|
||||
Pointer gtk_check_menu_item_new_with_mnemonic(String label);
|
||||
|
||||
/**
|
||||
* Sets the image of image_menu_item to the given widget. Note that it depends on the show-menu-images setting whether the image
|
||||
* will be displayed or not.
|
||||
* <p>
|
||||
* gtk_image_menu_item_set_image has been deprecated since version 3.10 and should not be used in newly-written code.
|
||||
*/
|
||||
void gtk_image_menu_item_set_image(Pointer image_menu_item, Pointer image);
|
||||
|
||||
/**
|
||||
* If TRUE, the menu item will ignore the "gtk-menu-images" setting and always show the image, if available.
|
||||
* Use this property if the menuitem would be useless or hard to use without the image
|
||||
* <p>
|
||||
* gtk_image_menu_item_set_always_show_image has been deprecated since version 3.10 and should not be used in newly-written code.
|
||||
*/
|
||||
void gtk_image_menu_item_set_always_show_image(Pointer menu_item, boolean forceShow);
|
||||
|
||||
/**
|
||||
* Creates an empty status icon object.
|
||||
* <p>
|
||||
* gtk_status_icon_new has been deprecated since version 3.14 and should not be used in newly-written code.
|
||||
* Use notifications
|
||||
*/
|
||||
Pointer gtk_status_icon_new();
|
||||
|
||||
/**
|
||||
* Obtains the root window (parent all other windows are inside) for the default display and screen.
|
||||
*
|
||||
* @return the default root window
|
||||
*/
|
||||
Pointer gdk_get_default_root_window();
|
||||
|
||||
/**
|
||||
* Gets the default screen for the default display. (See gdk_display_get_default()).
|
||||
*
|
||||
* @return a GdkScreen, or NULL if there is no default display.
|
||||
*
|
||||
* @since 2.2
|
||||
*/
|
||||
Pointer gdk_screen_get_default();
|
||||
|
||||
/**
|
||||
* Gets the resolution for font handling on the screen; see gdk_screen_set_resolution() for full details.
|
||||
*
|
||||
* IE:
|
||||
*
|
||||
* The resolution for font handling on the screen. This is a scale factor between points specified in a PangoFontDescription and
|
||||
* cairo units. The default value is 96, meaning that a 10 point font will be 13 units high. (10 * 96. / 72. = 13.3).
|
||||
*
|
||||
* @return the current resolution, or -1 if no resolution has been set.
|
||||
*
|
||||
* @since Since: 2.10
|
||||
*/
|
||||
double gdk_screen_get_resolution(Pointer screen);
|
||||
|
||||
/**
|
||||
* Makes status_icon display the file filename . See gtk_status_icon_new_from_file() for details.
|
||||
* <p>
|
||||
* gtk_status_icon_set_from_file has been deprecated since version 3.14 and should not be used in newly-written code.
|
||||
* Use notifications
|
||||
*/
|
||||
void gtk_status_icon_set_from_file(Pointer widget, String label);
|
||||
|
||||
/**
|
||||
* Shows or hides a status icon.
|
||||
* <p>
|
||||
* gtk_status_icon_set_visible has been deprecated since version 3.14 and should not be used in newly-written code.
|
||||
* Use notifications
|
||||
*/
|
||||
void gtk_status_icon_set_visible(Pointer widget, boolean visible);
|
||||
|
||||
|
||||
/**
|
||||
* Sets text as the contents of the tooltip.
|
||||
* This function will take care of setting "has-tooltip" to TRUE and of the default handler for the "query-tooltip" signal.
|
||||
*
|
||||
* app indicators don't support this
|
||||
*
|
||||
* gtk_status_icon_set_tooltip_text has been deprecated since version 3.14 and should not be used in newly-written code.
|
||||
* Use notifications
|
||||
*/
|
||||
void gtk_status_icon_set_tooltip_text(Pointer widget, String tooltipText);
|
||||
|
||||
/**
|
||||
* Sets the title of this tray icon. This should be a short, human-readable, localized string describing the tray icon. It may be used
|
||||
* by tools like screen readers to render the tray icon.
|
||||
* <p>
|
||||
* gtk_status_icon_set_title has been deprecated since version 3.14 and should not be used in newly-written code.
|
||||
* Use notifications
|
||||
*/
|
||||
void gtk_status_icon_set_title(Pointer widget, String titleText);
|
||||
|
||||
/**
|
||||
* Sets the name of this tray icon. This should be a string identifying this icon. It is may be used for sorting the icons in the
|
||||
* tray and will not be shown to the user.
|
||||
* <p>
|
||||
* gtk_status_icon_set_name has been deprecated since version 3.14 and should not be used in newly-written code.
|
||||
* Use notifications
|
||||
*/
|
||||
void gtk_status_icon_set_name(Pointer widget, String name);
|
||||
|
||||
/**
|
||||
* Displays a menu and makes it available for selection.
|
||||
* <p>
|
||||
* gtk_menu_popup has been deprecated since version 3.22 and should not be used in newly-written code.
|
||||
* NOTE: Please use gtk_menu_popup_at_widget(), gtk_menu_popup_at_pointer(). or gtk_menu_popup_at_rect() instead
|
||||
*/
|
||||
void gtk_menu_popup(Pointer menu, Pointer widget, Pointer bla, Function func, Pointer data, int button, int time);
|
||||
|
||||
/**
|
||||
* Sets text on the menu_item label
|
||||
*/
|
||||
void gtk_menu_item_set_label(Pointer menu_item, String label);
|
||||
|
||||
/**
|
||||
* Adds a new GtkMenuItem to the end of the menu shell's item list.
|
||||
*/
|
||||
void gtk_menu_shell_append(Pointer menu_shell, Pointer child);
|
||||
|
||||
/**
|
||||
* Sets the sensitivity of a widget. A widget is sensitive if the user can interact with it. Insensitive widgets are "grayed out"
|
||||
* and the user can’t interact with them. Insensitive widgets are known as "inactive", "disabled", or "ghosted" in some other toolkits.
|
||||
*/
|
||||
void gtk_widget_set_sensitive(Pointer widget, boolean sensitive);
|
||||
|
||||
/**
|
||||
* Recursively shows a widget, and any child widgets (if the widget is a container)
|
||||
*/
|
||||
void gtk_widget_show_all(Pointer widget);
|
||||
|
||||
/**
|
||||
* Removes widget from container . widget must be inside container . Note that container will own a reference to widget , and that
|
||||
* this may be the last reference held; so removing a widget from its container can destroy that widget.
|
||||
* <p>
|
||||
* If you want to use widget again, you need to add a reference to it before removing it from a container, using g_object_ref().
|
||||
* If you don’t want to use widget again it’s usually more efficient to simply destroy it directly using gtk_widget_destroy()
|
||||
* since this will remove it from the container and help break any circular reference count cycles.
|
||||
*/
|
||||
void gtk_container_remove(Pointer parentWidget, Pointer widget);
|
||||
|
||||
/**
|
||||
* Destroys a widget.
|
||||
* When a widget is destroyed all references it holds on other objects will be released:
|
||||
* - if the widget is inside a container, it will be removed from its parent
|
||||
* - if the widget is a container, all its children will be destroyed, recursively
|
||||
* - if the widget is a top level, it will be removed from the list of top level widgets that GTK+ maintains internally
|
||||
* <p>
|
||||
* It's expected that all references held on the widget will also be released; you should connect to the "destroy" signal if you
|
||||
* hold a reference to widget and you wish to remove it when this function is called. It is not necessary to do so if you are
|
||||
* implementing a GtkContainer, as you'll be able to use the GtkContainerClass.remove() virtual function for that.
|
||||
* <p>
|
||||
* It's important to notice that gtk_widget_destroy() will only cause the widget to be finalized if no additional references,
|
||||
* acquired using g_object_ref(), are held on it. In case additional references are in place, the widget will be in an "inert" state
|
||||
* after calling this function; widget will still point to valid memory, allowing you to release the references you hold, but you
|
||||
* may not query the widget's own state.
|
||||
* <p>
|
||||
* NOTE You should typically call this function on top level widgets, and rarely on child widgets.
|
||||
*/
|
||||
void gtk_widget_destroy(Pointer widget);
|
||||
|
||||
/**
|
||||
* Gets the GtkSettings object for the screen, creating it if necessary.
|
||||
*
|
||||
* @since 2.2
|
||||
*/
|
||||
Pointer gtk_settings_get_for_screen(Pointer screen);
|
||||
|
||||
/**
|
||||
* Gets the GtkSettings object for the default GDK screen, creating it if necessary.
|
||||
*
|
||||
* @since 2.2
|
||||
*/
|
||||
Pointer gtk_settings_get_default();
|
||||
|
||||
/**
|
||||
* Finds all matching RC styles for a given widget, composites them together, and then creates a GtkStyle representing the composite
|
||||
* appearance. (GTK+ actually keeps a cache of previously created styles, so a new style may not be created.)
|
||||
*/
|
||||
GtkStyle gtk_rc_get_style(Pointer widget);
|
||||
|
||||
/**
|
||||
* Adds widget to container . Typically used for simple containers such as GtkWindow, GtkFrame, or GtkButton; for more complicated
|
||||
* layout containers such as GtkBox or GtkTable, this function will pick default packing parameters that may not be correct. So
|
||||
* consider functions such as gtk_box_pack_start() and gtk_table_attach() as an alternative to gtk_container_add() in those cases.
|
||||
* A widget may be added to only one container at a time; you can't place the same widget inside two different containers.
|
||||
*/
|
||||
void gtk_container_add(Pointer offscreen, Pointer widget);
|
||||
|
||||
/**
|
||||
* Get's the child from a GTK Bin object
|
||||
*/
|
||||
Pointer gtk_bin_get_child(Pointer bin);
|
||||
|
||||
/**
|
||||
* Gets the PangoLayout used to display the label. The layout is useful to e.g. convert text positions to pixel positions, in
|
||||
* combination with gtk_label_get_layout_offsets(). The returned layout is owned by the label so need not be freed by the caller.
|
||||
*
|
||||
* The label is free to recreate its layout at any time, so it should be considered read-only.
|
||||
*/
|
||||
Pointer gtk_label_get_layout(Pointer label);
|
||||
|
||||
/**
|
||||
* Computes the logical and ink extents of layout in device units. This function just calls pango_layout_get_extents() followed
|
||||
* by two pango_extents_to_pixels() calls, rounding ink_rect and logical_rect such that the rounded rectangles fully contain the
|
||||
* unrounded one (that is, passes them as first argument to pango_extents_to_pixels()).
|
||||
*
|
||||
* @param layout a PangoLayout
|
||||
* @param ink_rect rectangle used to store the extents of the layout as drawn or NULL to indicate that the result is not needed.
|
||||
* @param logical_rect rectangle used to store the logical extents of the layout or NULL to indicate that the result is not needed.
|
||||
*/
|
||||
void pango_layout_get_pixel_extents(Pointer layout, Pointer ink_rect, Pointer logical_rect);
|
||||
|
||||
/**
|
||||
* Creates the GDK (windowing system) resources associated with a widget. For example, widget->window will be created when a widget
|
||||
* is realized. Normally realization happens implicitly; if you show a widget and all its parent containers, then the widget will
|
||||
* be realized and mapped automatically.
|
||||
*
|
||||
* Realizing a widget requires all the widget’s parent widgets to be realized; calling gtk_widget_realize() realizes the widget’s
|
||||
* parents in addition to widget itself. If a widget is not yet inside a toplevel window when you realize it, bad things will happen.
|
||||
*
|
||||
* This function is primarily used in widget implementations, and isn’t very useful otherwise. Many times when you think you might
|
||||
* need it, a better approach is to connect to a signal that will be called after the widget is realized automatically, such as
|
||||
* "draw". Or simply g_signal_connect() to the "realize" signal.
|
||||
*/
|
||||
void gtk_widget_realize(Pointer widget);
|
||||
|
||||
/**
|
||||
* Creates a toplevel container widget that is used to retrieve snapshots of widgets without showing them on the screen.
|
||||
*
|
||||
* @since 2.20
|
||||
*/
|
||||
Pointer gtk_offscreen_window_new();
|
||||
|
||||
/**
|
||||
* This function is typically used when implementing a GtkContainer subclass. Obtains the preferred size of a widget. The
|
||||
* container uses this information to arrange its child widgets and decide what size allocations to give them with
|
||||
* gtk_widget_size_allocate().
|
||||
*
|
||||
* You can also call this function from an application, with some caveats. Most notably, getting a size request requires the
|
||||
* widget to be associated with a screen, because font information may be needed. Multihead-aware applications should keep this in mind.
|
||||
*
|
||||
* Also remember that the size request is not necessarily the size a widget will actually be allocated.
|
||||
*/
|
||||
void gtk_widget_size_request(final Pointer widget, final Pointer requisition);
|
||||
|
||||
/**
|
||||
* Creates a new GtkImageMenuItem containing the image and text from a stock item. Some stock ids have preprocessor macros
|
||||
* like GTK_STOCK_OK and GTK_STOCK_APPLY.
|
||||
*
|
||||
* @param stock_id the name of the stock item.
|
||||
* @param accel_group the GtkAccelGroup to add the menu items accelerator to, or NULL.
|
||||
*
|
||||
* @return a new GtkImageMenuItem.
|
||||
*/
|
||||
Pointer gtk_image_menu_item_new_from_stock(String stock_id, Pointer accel_group);
|
||||
|
||||
/**
|
||||
* A convenience function for launching the default application to show the uri. Like gtk_show_uri_on_window(), but takes a screen
|
||||
* as transient parent instead of a window.
|
||||
*
|
||||
* @param timestamp GDK_CURRENT_TIME = 0 (this is what you should use)
|
||||
* @since 2.14
|
||||
*/
|
||||
@Deprecated
|
||||
boolean gtk_show_uri(Pointer screen, String uri, int timestamp, Pointer error);
|
||||
|
||||
/**
|
||||
* Sets text as the contents of the tooltip. This function will take care of setting "has-tooltip" to TRUE and of the default
|
||||
* handler for the "query-tooltip" signal. Null text will remove the tooltip
|
||||
*
|
||||
* @since 2.12
|
||||
*/
|
||||
void gtk_widget_set_tooltip_text(Pointer widget, String text);
|
||||
|
||||
/**
|
||||
* Gets the default GdkDisplay. This is a convenience function for gdk_display_manager_get_default_display (gdk_display_manager_get()).
|
||||
*
|
||||
* @since: 2.2
|
||||
*/
|
||||
Pointer gdk_display_get_default();
|
||||
}
|
||||
|
|
@ -0,0 +1,219 @@
|
|||
/*
|
||||
* Copyright 2017 dorkbox, llc
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package dorkbox.jna.linux;
|
||||
|
||||
import com.sun.jna.Function;
|
||||
import com.sun.jna.Pointer;
|
||||
|
||||
import dorkbox.jna.linux.structs.GtkStyle;
|
||||
|
||||
/**
|
||||
* Bindings for GTK+ 2. Bindings that are exclusively for GTK+ 3 are in that respective class
|
||||
* <p>
|
||||
* Direct-mapping, See: https://github.com/java-native-access/jna/blob/master/www/DirectMapping.md
|
||||
*/
|
||||
public
|
||||
class Gtk2 implements Gtk {
|
||||
// objdump -T /usr/lib/x86_64-linux-gnu/libgtk-x11-2.0.so.0 | grep gtk
|
||||
|
||||
@Override
|
||||
public native
|
||||
boolean gtk_init_check(final int argc);
|
||||
|
||||
@Override
|
||||
public native
|
||||
GMainLoop g_main_loop_new(Pointer context, boolean is_running);
|
||||
|
||||
@Override
|
||||
public native
|
||||
GMainContext g_main_loop_get_context(GMainLoop loop);
|
||||
|
||||
@Override
|
||||
public native
|
||||
void g_main_loop_run(GMainLoop loop);
|
||||
|
||||
@Override
|
||||
public native
|
||||
void g_main_context_invoke(GMainContext c, FuncCallback func, Pointer data);
|
||||
|
||||
@Override
|
||||
public native
|
||||
void g_main_loop_quit(GMainLoop loop);
|
||||
|
||||
@Override
|
||||
public native
|
||||
Pointer gtk_menu_new();
|
||||
|
||||
@Override
|
||||
public native
|
||||
void gtk_menu_item_set_submenu(final Pointer menuEntry, final Pointer menu);
|
||||
|
||||
@Override
|
||||
public native
|
||||
Pointer gtk_separator_menu_item_new();
|
||||
|
||||
@Override
|
||||
public native
|
||||
Pointer gtk_image_new_from_file(final String iconPath);
|
||||
|
||||
@Override
|
||||
public native
|
||||
void gtk_check_menu_item_set_active(final Pointer check_menu_item, final boolean isChecked);
|
||||
|
||||
@Override
|
||||
public native
|
||||
Pointer gtk_image_menu_item_new_with_mnemonic(final String label);
|
||||
|
||||
@Override
|
||||
public native
|
||||
Pointer gtk_check_menu_item_new_with_mnemonic(final String label);
|
||||
|
||||
@Override
|
||||
public native
|
||||
void gtk_image_menu_item_set_image(final Pointer image_menu_item, final Pointer image);
|
||||
|
||||
@Override
|
||||
public native
|
||||
void gtk_image_menu_item_set_always_show_image(final Pointer menu_item, final boolean forceShow);
|
||||
|
||||
@Override
|
||||
public native
|
||||
Pointer gtk_status_icon_new();
|
||||
|
||||
@Override
|
||||
public native
|
||||
Pointer gdk_get_default_root_window();
|
||||
|
||||
@Override
|
||||
public native
|
||||
Pointer gdk_screen_get_default();
|
||||
|
||||
@Override
|
||||
public native
|
||||
double gdk_screen_get_resolution(final Pointer screen);
|
||||
|
||||
@Override
|
||||
public native
|
||||
void gtk_status_icon_set_from_file(final Pointer widget, final String label);
|
||||
|
||||
@Override
|
||||
public native
|
||||
void gtk_status_icon_set_visible(final Pointer widget, final boolean visible);
|
||||
|
||||
@Override
|
||||
public native
|
||||
void gtk_status_icon_set_tooltip_text(final Pointer widget, final String tooltipText);
|
||||
|
||||
@Override
|
||||
public native
|
||||
void gtk_status_icon_set_title(final Pointer widget, final String titleText);
|
||||
|
||||
@Override
|
||||
public native
|
||||
void gtk_status_icon_set_name(final Pointer widget, final String name);
|
||||
|
||||
@Override
|
||||
public native
|
||||
void gtk_menu_popup(final Pointer menu,
|
||||
final Pointer widget,
|
||||
final Pointer bla,
|
||||
final Function func,
|
||||
final Pointer data,
|
||||
final int button,
|
||||
final int time);
|
||||
|
||||
@Override
|
||||
public native
|
||||
void gtk_menu_item_set_label(final Pointer menu_item, final String label);
|
||||
|
||||
@Override
|
||||
public native
|
||||
void gtk_menu_shell_append(final Pointer menu_shell, final Pointer child);
|
||||
|
||||
@Override
|
||||
public native
|
||||
void gtk_widget_set_sensitive(final Pointer widget, final boolean sensitive);
|
||||
|
||||
@Override
|
||||
public native
|
||||
void gtk_widget_show_all(final Pointer widget);
|
||||
|
||||
@Override
|
||||
public native
|
||||
void gtk_container_remove(final Pointer parentWidget, final Pointer widget);
|
||||
|
||||
@Override
|
||||
public native
|
||||
void gtk_widget_destroy(final Pointer widget);
|
||||
|
||||
@Override
|
||||
public native
|
||||
Pointer gtk_settings_get_for_screen(final Pointer screen);
|
||||
|
||||
@Override
|
||||
public native
|
||||
Pointer gtk_settings_get_default();
|
||||
|
||||
@Override
|
||||
public native
|
||||
GtkStyle gtk_rc_get_style(final Pointer widget);
|
||||
|
||||
@Override
|
||||
public native
|
||||
void gtk_container_add(final Pointer offscreen, final Pointer widget);
|
||||
|
||||
@Override
|
||||
public native
|
||||
Pointer gtk_bin_get_child(final Pointer bin);
|
||||
|
||||
@Override
|
||||
public native
|
||||
Pointer gtk_label_get_layout(final Pointer label);
|
||||
|
||||
@Override
|
||||
public native
|
||||
void pango_layout_get_pixel_extents(final Pointer layout, final Pointer ink_rect, final Pointer logical_rect);
|
||||
|
||||
@Override
|
||||
public native
|
||||
void gtk_widget_realize(final Pointer widget);
|
||||
|
||||
@Override
|
||||
public native
|
||||
Pointer gtk_offscreen_window_new();
|
||||
|
||||
@Override
|
||||
public native
|
||||
void gtk_widget_size_request(final Pointer widget, final Pointer requisition);
|
||||
|
||||
@Override
|
||||
public native
|
||||
Pointer gtk_image_menu_item_new_from_stock(final String stock_id, final Pointer accel_group);
|
||||
|
||||
@Deprecated
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public native
|
||||
boolean gtk_show_uri(final Pointer screen, final String uri, final int timestamp, final Pointer error);
|
||||
|
||||
@Override
|
||||
public native
|
||||
void gtk_widget_set_tooltip_text(final Pointer widget, final String text);
|
||||
|
||||
@Override
|
||||
public native
|
||||
Pointer gdk_display_get_default();
|
||||
}
|
|
@ -0,0 +1,314 @@
|
|||
/*
|
||||
* Copyright 2017 dorkbox, llc
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package dorkbox.jna.linux;
|
||||
|
||||
import com.sun.jna.Function;
|
||||
import com.sun.jna.NativeLibrary;
|
||||
import com.sun.jna.Pointer;
|
||||
|
||||
import dorkbox.jna.linux.structs.GtkStyle;
|
||||
|
||||
/**
|
||||
* bindings for GTK+ 3.
|
||||
* <p>
|
||||
* Direct-mapping, See: https://github.com/java-native-access/jna/blob/master/www/DirectMapping.md
|
||||
*/
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
public
|
||||
class Gtk3 implements Gtk {
|
||||
private static Function gdk_window_get_scale_factor = null;
|
||||
private static Function gtk_show_uri_on_window = null;
|
||||
|
||||
// objdump -T /usr/lib/x86_64-linux-gnu/libgtk-3.so.0 | grep gtk
|
||||
// objdump -T /usr/local/lib/libgtk-3.so.0 | grep gtk
|
||||
|
||||
/**
|
||||
* Loads version specific methods
|
||||
*/
|
||||
static
|
||||
void loadMethods(final NativeLibrary library) {
|
||||
// Abusing static fields this way is not proper, but it gets the job done nicely.
|
||||
|
||||
if (GtkCheck.gtkIsGreaterOrEqual(3, 10, 0)) {
|
||||
gdk_window_get_scale_factor = library.getFunction("gdk_window_get_scale_factor");
|
||||
}
|
||||
|
||||
if (GtkCheck.gtkIsGreaterOrEqual(3, 22, 0)) {
|
||||
gtk_show_uri_on_window = library.getFunction("gtk_show_uri_on_window");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the minimum and natural size of a widget, taking into account the widget’s preference for height-for-width management.
|
||||
* <p>
|
||||
* This is used to retrieve a suitable size by container widgets which do not impose any restrictions on the child placement.
|
||||
* It can be used to deduce toplevel window and menu sizes as well as child widgets in free-form containers such as GtkLayout.
|
||||
* <p>
|
||||
* Handle with care. Note that the natural height of a height-for-width widget will generally be a smaller size than the minimum
|
||||
* height, since the required height for the natural width is generally smaller than the required height for the minimum width.
|
||||
* <p>
|
||||
* Use gtk_widget_get_preferred_height_and_baseline_for_width() if you want to support baseline alignment.
|
||||
*
|
||||
* @param widget a GtkWidget instance
|
||||
* @param minimum_size location for storing the minimum size, or NULL.
|
||||
* @param natural_size location for storing the natural size, or NULL.
|
||||
*/
|
||||
public native
|
||||
void gtk_widget_get_preferred_size(final Pointer widget, final Pointer minimum_size, final Pointer natural_size);
|
||||
|
||||
/**
|
||||
* Returns the internal scale factor that maps from window coordinates to the actual device pixels. On traditional systems this is 1,
|
||||
* but on very high density outputs this can be a higher value (often 2).
|
||||
* <p>
|
||||
* A higher value means that drawing is automatically scaled up to a higher resolution, so any code doing drawing will automatically
|
||||
* look nicer. However, if you are supplying pixel-based data the scale value can be used to determine whether to use a pixel
|
||||
* resource with higher resolution data.
|
||||
* <p>
|
||||
* The scale of a window may change during runtime, if this happens a configure event will be sent to the toplevel window.
|
||||
*
|
||||
* @return the scale factor
|
||||
*
|
||||
* @since 3.10
|
||||
*/
|
||||
public
|
||||
int gdk_window_get_scale_factor(Pointer window) {
|
||||
if (gdk_window_get_scale_factor != null) {
|
||||
return gdk_window_get_scale_factor.invokeInt(new Object[]{window});
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return TRUE on success, FALSE on error
|
||||
*
|
||||
* @since: 3.22
|
||||
*/
|
||||
public
|
||||
boolean gtk_show_uri_on_window(final Pointer parent, final String uri, final int timestamp, final Pointer error) {
|
||||
if (gtk_show_uri_on_window != null) {
|
||||
return (Boolean) gtk_show_uri_on_window.invoke(Boolean.class, new Object[] {parent, uri, timestamp, error});
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////
|
||||
//// GTK2 methods
|
||||
///////////////////////////
|
||||
|
||||
/**
|
||||
* This function is typically used when implementing a GtkContainer subclass. Obtains the preferred size of a widget. The
|
||||
* container uses this information to arrange its child widgets and decide what size allocations to give them with
|
||||
* gtk_widget_size_allocate().
|
||||
*
|
||||
* You can also call this function from an application, with some caveats. Most notably, getting a size request requires the
|
||||
* widget to be associated with a screen, because font information may be needed. Multihead-aware applications should keep this in mind.
|
||||
*
|
||||
* Also remember that the size request is not necessarily the size a widget will actually be allocated.
|
||||
*/
|
||||
@Override
|
||||
public
|
||||
void gtk_widget_size_request(final Pointer widget, final Pointer requisition) {
|
||||
this.gtk_widget_get_preferred_size(widget, requisition, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public native
|
||||
boolean gtk_init_check(final int argc);
|
||||
|
||||
@Override
|
||||
public native
|
||||
GMainLoop g_main_loop_new(Pointer context, boolean is_running);
|
||||
|
||||
@Override
|
||||
public native
|
||||
GMainContext g_main_loop_get_context(GMainLoop loop);
|
||||
|
||||
@Override
|
||||
public native
|
||||
void g_main_loop_run(GMainLoop loop);
|
||||
|
||||
@Override
|
||||
public native
|
||||
void g_main_context_invoke(GMainContext c, FuncCallback func, Pointer data);
|
||||
|
||||
@Override
|
||||
public native
|
||||
void g_main_loop_quit(GMainLoop loop);
|
||||
|
||||
@Override
|
||||
public native
|
||||
Pointer gtk_menu_new();
|
||||
|
||||
@Override
|
||||
public native
|
||||
void gtk_menu_item_set_submenu(final Pointer menuEntry, final Pointer menu);
|
||||
|
||||
@Override
|
||||
public native
|
||||
Pointer gtk_separator_menu_item_new();
|
||||
|
||||
@Override
|
||||
public native
|
||||
Pointer gtk_image_new_from_file(final String iconPath);
|
||||
|
||||
@Override
|
||||
public native
|
||||
void gtk_check_menu_item_set_active(final Pointer check_menu_item, final boolean isChecked);
|
||||
|
||||
@Override
|
||||
public native
|
||||
Pointer gtk_image_menu_item_new_with_mnemonic(final String label);
|
||||
|
||||
@Override
|
||||
public native
|
||||
Pointer gtk_check_menu_item_new_with_mnemonic(final String label);
|
||||
|
||||
@Override
|
||||
public native
|
||||
void gtk_image_menu_item_set_image(final Pointer image_menu_item, final Pointer image);
|
||||
|
||||
@Override
|
||||
public native
|
||||
void gtk_image_menu_item_set_always_show_image(final Pointer menu_item, final boolean forceShow);
|
||||
|
||||
@Override
|
||||
public native
|
||||
Pointer gtk_status_icon_new();
|
||||
|
||||
@Override
|
||||
public native
|
||||
Pointer gdk_get_default_root_window();
|
||||
|
||||
@Override
|
||||
public native
|
||||
Pointer gdk_screen_get_default();
|
||||
|
||||
@Override
|
||||
public native
|
||||
double gdk_screen_get_resolution(final Pointer screen);
|
||||
|
||||
@Override
|
||||
public native
|
||||
void gtk_status_icon_set_from_file(final Pointer widget, final String label);
|
||||
|
||||
@Override
|
||||
public native
|
||||
void gtk_status_icon_set_visible(final Pointer widget, final boolean visible);
|
||||
|
||||
@Override
|
||||
public native
|
||||
void gtk_status_icon_set_tooltip_text(final Pointer widget, final String tooltipText);
|
||||
|
||||
@Override
|
||||
public native
|
||||
void gtk_status_icon_set_title(final Pointer widget, final String titleText);
|
||||
|
||||
@Override
|
||||
public native
|
||||
void gtk_status_icon_set_name(final Pointer widget, final String name);
|
||||
|
||||
@Override
|
||||
public native
|
||||
void gtk_menu_popup(final Pointer menu,
|
||||
final Pointer widget,
|
||||
final Pointer bla,
|
||||
final Function func,
|
||||
final Pointer data,
|
||||
final int button,
|
||||
final int time);
|
||||
|
||||
@Override
|
||||
public native
|
||||
void gtk_menu_item_set_label(final Pointer menu_item, final String label);
|
||||
|
||||
@Override
|
||||
public native
|
||||
void gtk_menu_shell_append(final Pointer menu_shell, final Pointer child);
|
||||
|
||||
@Override
|
||||
public native
|
||||
void gtk_widget_set_sensitive(final Pointer widget, final boolean sensitive);
|
||||
|
||||
@Override
|
||||
public native
|
||||
void gtk_widget_show_all(final Pointer widget);
|
||||
|
||||
@Override
|
||||
public native
|
||||
void gtk_container_remove(final Pointer parentWidget, final Pointer widget);
|
||||
|
||||
@Override
|
||||
public native
|
||||
void gtk_widget_destroy(final Pointer widget);
|
||||
|
||||
@Override
|
||||
public native
|
||||
Pointer gtk_settings_get_for_screen(final Pointer screen);
|
||||
|
||||
@Override
|
||||
public native
|
||||
Pointer gtk_settings_get_default();
|
||||
|
||||
@Override
|
||||
public native
|
||||
GtkStyle gtk_rc_get_style(final Pointer widget);
|
||||
|
||||
@Override
|
||||
public native
|
||||
void gtk_container_add(final Pointer offscreen, final Pointer widget);
|
||||
|
||||
@Override
|
||||
public native
|
||||
Pointer gtk_bin_get_child(final Pointer bin);
|
||||
|
||||
@Override
|
||||
public native
|
||||
Pointer gtk_label_get_layout(final Pointer label);
|
||||
|
||||
@Override
|
||||
public native
|
||||
void pango_layout_get_pixel_extents(final Pointer layout, final Pointer ink_rect, final Pointer logical_rect);
|
||||
|
||||
@Override
|
||||
public native
|
||||
void gtk_widget_realize(final Pointer widget);
|
||||
|
||||
@Override
|
||||
public native
|
||||
Pointer gtk_offscreen_window_new();
|
||||
|
||||
@Override
|
||||
public native
|
||||
Pointer gtk_image_menu_item_new_from_stock(final String stock_id, final Pointer accel_group);
|
||||
|
||||
@Deprecated
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public native
|
||||
boolean gtk_show_uri(final Pointer screen, final String uri, final int timestamp, final Pointer error);
|
||||
|
||||
@Override
|
||||
public native
|
||||
void gtk_widget_set_tooltip_text(final Pointer widget, final String text);
|
||||
|
||||
@Override
|
||||
public native
|
||||
Pointer gdk_display_get_default();
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Copyright 2017 dorkbox, llc
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package dorkbox.jna.linux;
|
||||
|
||||
/**
|
||||
* bindings for GTK+ 3 version info.
|
||||
* <p>
|
||||
* Direct-mapping, See: https://github.com/java-native-access/jna/blob/master/www/DirectMapping.md
|
||||
*/
|
||||
public
|
||||
class Gtk3VersionInfo {
|
||||
// objdump -T /usr/lib/x86_64-linux-gnu/libgtk-3.so.0 | grep gtk
|
||||
// objdump -T /usr/local/lib/libgtk-3.so.0 | grep gtk
|
||||
|
||||
public native
|
||||
int gtk_get_major_version();
|
||||
|
||||
public native
|
||||
int gtk_get_minor_version();
|
||||
|
||||
public native
|
||||
int gtk_get_micro_version();
|
||||
}
|
|
@ -0,0 +1,148 @@
|
|||
/*
|
||||
* Copyright 2017 dorkbox, llc
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package dorkbox.jna.linux;
|
||||
|
||||
import dorkbox.jna.rendering.RenderProvider;
|
||||
import dorkbox.os.OS;
|
||||
|
||||
/**
|
||||
* Accessor methods/logic for determining if GTK is already loaded by the Swing/JavaFX/SWT, or if GTK has been manually loaded via
|
||||
* GtkEventDispatch.startGui().
|
||||
*/
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
public
|
||||
class GtkCheck {
|
||||
/**
|
||||
* Only valid if `isGtkLoaded=true`. Determine if the application is running via GTK2.
|
||||
* <p>
|
||||
* This does not cause GTK to load, where calls to Gtk.isGtk2 will
|
||||
*/
|
||||
public static volatile boolean isGtk2 = false;
|
||||
|
||||
/**
|
||||
* Only valid if `isGtkLoaded=true`. Determine if the application is running via GTK3.
|
||||
* <p>
|
||||
* This does not cause GTK to load, where calls to Gtk.isGtk2 will
|
||||
*/
|
||||
public static volatile boolean isGtk3 = false;
|
||||
|
||||
/**
|
||||
* Determine if the application has *MANUALLY* loaded GTK yet or not. This does not cause GTK to load, where calls to Gtk.isLoaded will
|
||||
*/
|
||||
public static volatile boolean isGtkLoaded = false;
|
||||
|
||||
|
||||
/** If GTK is loaded, this is the GTK MAJOR version */
|
||||
public static volatile int MAJOR = 0;
|
||||
|
||||
/** If GTK is loaded, this is the GTK MINOR version */
|
||||
public static volatile int MINOR = 0;
|
||||
|
||||
/** If GTK is loaded, this is the GTK MICRO version */
|
||||
public static volatile int MICRO = 0;
|
||||
|
||||
|
||||
/**
|
||||
* @return true if the currently loaded GTK version is greater to or equal to the passed-in major.minor.mico
|
||||
*/
|
||||
public static
|
||||
boolean gtkIsGreaterOrEqual(final int major, final int minor, final int micro) {
|
||||
if (MAJOR > major) {
|
||||
return true;
|
||||
}
|
||||
if (MAJOR < major) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (MINOR > minor) {
|
||||
return true;
|
||||
}
|
||||
if (MINOR < minor) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (MICRO > micro) {
|
||||
return true;
|
||||
}
|
||||
if (MICRO < micro) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// same exact version
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is agnostic w.r.t. how GTK is loaded, which can be manually loaded or loaded via JavaFX/SWT/Swing.
|
||||
*
|
||||
* NOTE: this WILL NOT attempt to load swing, and will use reflection for JAVA <=8 to check GTK version info
|
||||
*
|
||||
* @return the version of GTK loaded. 0=no GTK loaded (or unknown), 2=GTK2, 3=GTK3
|
||||
*/
|
||||
public static
|
||||
int getLoadedGtkVersion() {
|
||||
// if we have ALREADY loaded GTK, then return that information.
|
||||
if (isGtkLoaded) {
|
||||
if (isGtk3) {
|
||||
return 3;
|
||||
} else {
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
||||
int gtkVersion = RenderProvider.getGtkVersion();
|
||||
if (gtkVersion > 0) {
|
||||
return gtkVersion;
|
||||
}
|
||||
|
||||
/*
|
||||
* Checks to see if GTK is loaded by Swing from the "Look and Feel", and if so - which version is loaded.
|
||||
*
|
||||
* NOTE: if the UI uses the 'getSystemLookAndFeelClassName' and is on Linux and it's the GtkLookAndFeel,
|
||||
* this will cause GTK2 to get loaded FIRST, which will cause conflicts if one tries to use GTK3 (and it's GTK2)
|
||||
*
|
||||
* The **ONLY** issue we have is if WE are GTK3 and SWING is GTK2...
|
||||
*/
|
||||
|
||||
// java 8 cannot load GTK3. But we can know if GTK was loaded yet or not
|
||||
if (OS.INSTANCE.getJavaVersion() <= 8) {
|
||||
try {
|
||||
// Don't want to load the toolkit!!!
|
||||
Class<?> toolkitClass = Class.forName("java.awt.Toolkit");
|
||||
java.lang.reflect.Field kitField = toolkitClass.getDeclaredField("toolkit");
|
||||
kitField.setAccessible(true);
|
||||
Object toolkit = kitField.get(null);
|
||||
if (toolkit != null) {
|
||||
Class<?> unixTkClazz = Class.forName("sun.awt.UNIXToolkit");
|
||||
if (unixTkClazz.isAssignableFrom(toolkit.getClass())) {
|
||||
java.lang.reflect.Field field = unixTkClazz.getDeclaredField("nativeGTKLoaded");
|
||||
field.setAccessible(true);
|
||||
Boolean o = (Boolean) field.get(toolkit);
|
||||
//noinspection UnnecessaryUnboxing
|
||||
if (o != null && o.booleanValue()) {
|
||||
// if gtk is loaded, it **must* be version 2, since java <=8 cannot load GTK3
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Throwable ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
// don't know without forcing GTK to potentially load
|
||||
return 0;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,295 @@
|
|||
/*
|
||||
* Copyright 2015 dorkbox, llc
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package dorkbox.jna.linux;
|
||||
|
||||
import static dorkbox.jna.linux.Gtk2.FALSE;
|
||||
import static dorkbox.jna.linux.Gtk2.Gtk2;
|
||||
|
||||
import java.awt.event.ActionListener;
|
||||
import java.util.LinkedList;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.sun.jna.Pointer;
|
||||
|
||||
import dorkbox.jna.rendering.RenderProvider;
|
||||
|
||||
|
||||
public
|
||||
class GtkEventDispatch {
|
||||
static boolean FORCE_GTK2 = false;
|
||||
static boolean PREFER_GTK3 = false;
|
||||
static boolean DEBUG = false;
|
||||
|
||||
// have to save these in a field to prevent GC on the objects (since they go out-of-scope from java)
|
||||
private static final LinkedList<FuncCallback> gtkCallbacks = new LinkedList<FuncCallback>();
|
||||
|
||||
// This is required because the EDT needs to have it's own value for this boolean, that is a different value than the main thread
|
||||
private static ThreadLocal<Boolean> isDispatch = new ThreadLocal<Boolean>() {
|
||||
@Override
|
||||
protected
|
||||
Boolean initialValue() {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
private static boolean started = false;
|
||||
|
||||
@SuppressWarnings("FieldCanBeLocal")
|
||||
private static Thread gtkUpdateThread = null;
|
||||
|
||||
private static GMainLoop mainloop;
|
||||
private static GMainContext context;
|
||||
|
||||
// when debugging the EDT, we need a longer timeout.
|
||||
private static final boolean debugEDT = false;
|
||||
|
||||
// timeout is in seconds
|
||||
private static final int TIMEOUT = debugEDT ? 10000000 : 2;
|
||||
|
||||
|
||||
/**
|
||||
* This will load and start GTK
|
||||
*/
|
||||
public static synchronized
|
||||
void startGui(final boolean forceGtk2, final boolean preferGkt3, final boolean debug) {
|
||||
// only permit one startup per JVM instance
|
||||
if (!started) {
|
||||
started = true;
|
||||
|
||||
GtkEventDispatch.FORCE_GTK2 = forceGtk2;
|
||||
GtkEventDispatch.PREFER_GTK3 = preferGkt3;
|
||||
GtkEventDispatch.DEBUG = debug;
|
||||
|
||||
// startup the GTK GUI event loop. There can be multiple/nested loops.
|
||||
if (!GtkLoader.alreadyRunningGTK) {
|
||||
// If JavaFX/SWT is used, this is UNNECESSARY (we can detect if the GTK main_loop is running)
|
||||
|
||||
gtkUpdateThread = new Thread() {
|
||||
@Override
|
||||
public
|
||||
void run() {
|
||||
Glib.GLogFunc orig = null;
|
||||
if (debug) {
|
||||
// don't suppress GTK warnings in debug mode
|
||||
LoggerFactory.getLogger(GtkEventDispatch.class).debug("Running GTK Native Event Loop");
|
||||
} else {
|
||||
// NOTE: This can output warnings, so we suppress them. Additionally, setting System.err to null, or trying
|
||||
// to filter it, will not suppress these errors/warnings
|
||||
orig = Glib.g_log_set_default_handler(Glib.nullLogFunc, null);
|
||||
}
|
||||
|
||||
|
||||
if (!Gtk2.gtk_init_check(0)) {
|
||||
throw new RuntimeException("Error starting GTK");
|
||||
}
|
||||
|
||||
|
||||
// create the main-loop
|
||||
mainloop = Gtk2.g_main_loop_new(null, false);
|
||||
context = Gtk2.g_main_loop_get_context(mainloop);
|
||||
|
||||
// blocks until we quit the main loop
|
||||
Gtk2.g_main_loop_run(mainloop);
|
||||
|
||||
|
||||
if (orig != null) {
|
||||
Glib.g_log_set_default_handler(orig, null);
|
||||
}
|
||||
}
|
||||
};
|
||||
gtkUpdateThread.setDaemon(false); // explicitly NOT daemon so that this will hold the JVM open as necessary
|
||||
gtkUpdateThread.setName("GTK Native Event Loop");
|
||||
gtkUpdateThread.start();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Waits for the all posted events to GTK to finish loading
|
||||
*/
|
||||
@SuppressWarnings("Duplicates")
|
||||
public static synchronized
|
||||
void waitForEventsToComplete() {
|
||||
final CountDownLatch blockUntilStarted = new CountDownLatch(1);
|
||||
|
||||
dispatch(new Runnable() {
|
||||
@Override
|
||||
public
|
||||
void run() {
|
||||
blockUntilStarted.countDown();
|
||||
}
|
||||
});
|
||||
|
||||
if (!RenderProvider.isEventThread()) {
|
||||
try {
|
||||
if (!blockUntilStarted.await(10, TimeUnit.SECONDS)) {
|
||||
if (DEBUG) {
|
||||
LoggerFactory.getLogger(GtkEventDispatch.class)
|
||||
.error("Something is very wrong. The waitForEventsToComplete took longer than expected.",
|
||||
new Exception(""));
|
||||
}
|
||||
}
|
||||
|
||||
// we have to WAIT until all events are done processing, OTHERWISE we have initialization issues
|
||||
while (true) {
|
||||
Thread.sleep(100);
|
||||
|
||||
synchronized (gtkCallbacks) {
|
||||
if (gtkCallbacks.isEmpty()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispatch the runnable to GTK and wait until it has finished executing. If this is called while on the GTK dispatch thread, it will
|
||||
* immediately execute the task, otherwise it will submit the task to run on the FIFO queue.
|
||||
*/
|
||||
public static
|
||||
void dispatchAndWait(final Runnable runnable) {
|
||||
// if we are on the dispatch queue, do not block
|
||||
Boolean isDispatch = GtkEventDispatch.isDispatch.get();
|
||||
if (isDispatch) {
|
||||
// don't block. The ORIGINAL call (before items were queued) will still be blocking. If the original call was a "normal"
|
||||
// dispatch, then subsequent dispatchAndWait calls are irrelevant (as they happen in the GTK thread, and not the main thread).
|
||||
runnable.run();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
final CountDownLatch countDownLatch = new CountDownLatch(1);
|
||||
dispatch(new Runnable() {
|
||||
@Override
|
||||
public
|
||||
void run() {
|
||||
try {
|
||||
runnable.run();
|
||||
} catch (Exception e) {
|
||||
LoggerFactory.getLogger(GtkEventDispatch.class).error("Error during GTK run loop: ", e);
|
||||
} finally {
|
||||
countDownLatch.countDown();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// this is slightly different than how swing does it. We have a timeout here so that we can make sure that updates on the GUI
|
||||
// thread occur in REASONABLE time-frames, and alert the user if not.
|
||||
try {
|
||||
if (!countDownLatch.await(TIMEOUT, TimeUnit.SECONDS)) {
|
||||
if (DEBUG) {
|
||||
LoggerFactory.getLogger(GtkEventDispatch.class).error(
|
||||
"Something is very wrong. The Event Dispatch Queue took longer than " + TIMEOUT + " seconds " +
|
||||
"to complete.", new Exception(""));
|
||||
}
|
||||
else {
|
||||
throw new RuntimeException("Something is very wrong. The Event Dispatch Queue took longer than " + TIMEOUT +
|
||||
" seconds " + "to complete.");
|
||||
}
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
LoggerFactory.getLogger(GtkEventDispatch.class).error("Error waiting for dispatch to complete.", new Exception(""));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Best practices for GTK, is to call everything for it on the GTK THREAD. If we are currently on the dispatch thread, then this
|
||||
* task will execute immediately.
|
||||
*/
|
||||
public static
|
||||
void dispatch(final Runnable runnable) {
|
||||
if (GtkLoader.alreadyRunningGTK && RenderProvider.dispatch(runnable)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// not javafx
|
||||
// gtk/swt are **mostly** the same in how events are dispatched, so we can use "raw" gtk methods for SWT
|
||||
if (isDispatch.get()) {
|
||||
// Run directly on the dispatch thread. This will be false unless we are running the dispatch queue.
|
||||
runnable.run();
|
||||
return;
|
||||
}
|
||||
|
||||
final FuncCallback callback = new FuncCallback() {
|
||||
@Override
|
||||
public
|
||||
int callback(final Pointer data) {
|
||||
isDispatch.set(true);
|
||||
|
||||
try {
|
||||
runnable.run();
|
||||
} finally {
|
||||
isDispatch.set(false);
|
||||
}
|
||||
|
||||
synchronized (gtkCallbacks) {
|
||||
gtkCallbacks.removeFirst(); // now that we've 'handled' it, we can remove it from our callback list
|
||||
}
|
||||
|
||||
return FALSE; // don't want to call this again
|
||||
}
|
||||
};
|
||||
|
||||
synchronized (gtkCallbacks) {
|
||||
gtkCallbacks.offer(callback); // prevent GC from collecting this object before it can be called
|
||||
}
|
||||
|
||||
// explicitly invoke on our new GTK main loop context
|
||||
Gtk2.g_main_context_invoke(context, callback, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* required to properly setup the dispatch flag when using native menus
|
||||
*
|
||||
* @param callback will never be null.
|
||||
*/
|
||||
public static
|
||||
void proxyClick(final ActionListener callback) {
|
||||
isDispatch.set(true);
|
||||
|
||||
try {
|
||||
callback.actionPerformed(null);
|
||||
} catch (Throwable t) {
|
||||
LoggerFactory.getLogger(GtkEventDispatch.class)
|
||||
.error("Error during GTK click callback: ", t);
|
||||
}
|
||||
|
||||
isDispatch.set(false);
|
||||
}
|
||||
public static synchronized
|
||||
void shutdownGui() {
|
||||
dispatchAndWait(new Runnable() {
|
||||
@Override
|
||||
public
|
||||
void run() {
|
||||
// If JavaFX/SWT is used, this is UNNECESSARY (and will break SWT/JavaFX shutdown)
|
||||
if (!GtkLoader.alreadyRunningGTK) {
|
||||
Gtk2.g_main_loop_quit(mainloop);
|
||||
// Gtk2.gtk_main_quit();
|
||||
}
|
||||
|
||||
started = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,265 @@
|
|||
/*
|
||||
* Copyright 2015 dorkbox, llc
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package dorkbox.jna.linux;
|
||||
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.sun.jna.Function;
|
||||
import com.sun.jna.NativeLibrary;
|
||||
|
||||
import dorkbox.jna.JNA;
|
||||
import dorkbox.jna.rendering.RenderProvider;
|
||||
import dorkbox.os.OS;
|
||||
|
||||
/**
|
||||
* Bindings for GTK+ 2. Bindings that are exclusively for GTK+ 3 are in that respective class
|
||||
* <p>
|
||||
* Direct-mapping, See: https://github.com/java-native-access/jna/blob/master/www/DirectMapping.md
|
||||
*/
|
||||
@SuppressWarnings({"Duplicates", "SameParameterValue", "WeakerAccess"})
|
||||
public
|
||||
class GtkLoader {
|
||||
/**
|
||||
* Gets the version number.
|
||||
*/
|
||||
public static
|
||||
String getVersion() {
|
||||
return JNA.getVersion();
|
||||
}
|
||||
|
||||
// objdump -T /usr/lib/x86_64-linux-gnu/libgtk-x11-2.0.so.0 | grep gtk
|
||||
// objdump -T /usr/lib/x86_64-linux-gnu/libgtk-3.so.0 | grep gtk
|
||||
// objdump -T /usr/local/lib/libgtk-3.so.0 | grep gtk
|
||||
|
||||
// For funsies to look at, SyncThing did a LOT of work on compatibility in python (unfortunate for us, but interesting).
|
||||
// https://github.com/syncthing/syncthing-gtk/blob/b7a3bc00e3bb6d62365ae62b5395370f3dcc7f55/syncthing_gtk/statusicon.py
|
||||
|
||||
// NOTE: AppIndicator uses this info to figure out WHAT VERSION OF appindicator to use: GTK2 -> appindicator1, GTK3 -> appindicator3
|
||||
static boolean isGtk2;
|
||||
static boolean isGtk3;
|
||||
static boolean isLoaded;
|
||||
|
||||
|
||||
static boolean alreadyRunningGTK;
|
||||
|
||||
static Function gtk_status_icon_position_menu = null;
|
||||
|
||||
// use GtkCheck for a safe accessor of these
|
||||
static int MAJOR;
|
||||
static int MINOR;
|
||||
static int MICRO;
|
||||
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static final NativeLibrary libraryReference;
|
||||
|
||||
/*
|
||||
* We can have GTK v3 or v2.
|
||||
*
|
||||
* Observations:
|
||||
* JavaFX (java8) uses GTK2, and we can't load GTK3 if GTK2 symbols are loaded
|
||||
* SWT uses GTK2 or GTK3. We do not work with the GTK3 version of SWT.
|
||||
*/
|
||||
static {
|
||||
// Add this project to the updates system, which verifies this class + UUID + version information
|
||||
dorkbox.updates.Updates.INSTANCE.add(GtkLoader.class, "d712ab5998d742a1bc96ca2f7be197ce", getVersion());
|
||||
|
||||
|
||||
boolean forceGtk2 = GtkEventDispatch.FORCE_GTK2;
|
||||
// prefer GTK3 and force GTK2 are mutually exclusive
|
||||
boolean preferGtk3 = !forceGtk2 && GtkEventDispatch.PREFER_GTK3;
|
||||
|
||||
boolean _isGtk2 = false;
|
||||
boolean _isLoaded = false;
|
||||
boolean _alreadyRunningGTK = false;
|
||||
int major = 0;
|
||||
int minor = 0;
|
||||
int micro = 0;
|
||||
|
||||
boolean shouldLoadGtk = !(OS.INSTANCE.isWindows() || OS.INSTANCE.isMacOsX());
|
||||
if (!shouldLoadGtk) {
|
||||
_isLoaded = true;
|
||||
}
|
||||
|
||||
|
||||
// we can force the system to use the swing indicator, which WORKS, but doesn't support transparency in the icon. However, there
|
||||
// are certain GTK functions we might want to use (even if we are Swing or AWT), so we load GTK anyways...
|
||||
|
||||
// in some cases, we ALWAYS want to try GTK2 first
|
||||
String gtk2LibName = "gtk-x11-2.0";
|
||||
String gtk3LibName = "libgtk-3.so.0";
|
||||
|
||||
NativeLibrary library = null;
|
||||
|
||||
if (!_isLoaded && (forceGtk2 || !preferGtk3)) {
|
||||
try {
|
||||
library = JNA.register(gtk2LibName, Gtk2.class);
|
||||
|
||||
_isGtk2 = true;
|
||||
|
||||
major = library.getGlobalVariableAddress("gtk_major_version").getInt(0);
|
||||
minor = library.getGlobalVariableAddress("gtk_minor_version").getInt(0);
|
||||
micro = library.getGlobalVariableAddress("gtk_micro_version").getInt(0);
|
||||
|
||||
gtk_status_icon_position_menu = library.getFunction( "gtk_status_icon_position_menu");
|
||||
Function gtk_main_level = library.getFunction("gtk_main_level");
|
||||
|
||||
// when running inside of JavaFX, this will be '1'. All other times this should be '0'
|
||||
// when it's '1', it means that someone else has started GTK -- so we DO NOT NEED TO.
|
||||
_alreadyRunningGTK = gtk_main_level.invokeInt(null) != 0;
|
||||
_isLoaded = true;
|
||||
if (GtkEventDispatch.DEBUG) {
|
||||
LoggerFactory.getLogger(GtkLoader.class).debug("GTK: {}", gtk2LibName);
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
if (library != null) {
|
||||
library.close();
|
||||
}
|
||||
|
||||
if (GtkEventDispatch.DEBUG) {
|
||||
LoggerFactory.getLogger(GtkLoader.class).debug("Error loading library", e);
|
||||
}
|
||||
}
|
||||
|
||||
if (forceGtk2) {
|
||||
// don't try anything else if we forced GTK2
|
||||
_isLoaded = true;
|
||||
}
|
||||
}
|
||||
|
||||
// now for the defaults...
|
||||
|
||||
// start with version 3
|
||||
if (!_isLoaded) {
|
||||
try {
|
||||
// have to get the version information FIRST, because there are some really old GTK3 libraries out there.
|
||||
library = JNA.register(gtk3LibName, Gtk3VersionInfo.class);
|
||||
|
||||
Gtk3VersionInfo version = new Gtk3VersionInfo();
|
||||
major = version.gtk_get_major_version();
|
||||
minor = version.gtk_get_minor_version();
|
||||
micro = version.gtk_get_micro_version();
|
||||
|
||||
library.close();
|
||||
library = null;
|
||||
|
||||
library = JNA.register(gtk3LibName, Gtk3.class);
|
||||
|
||||
gtk_status_icon_position_menu = library.getFunction( "gtk_status_icon_position_menu");
|
||||
Function gtk_main_level = library.getFunction("gtk_main_level");
|
||||
|
||||
// when running inside of JavaFX, this will be '1'. All other times this should be '0'
|
||||
// when it's '1', it means that someone else has started GTK -- so we DO NOT NEED TO.
|
||||
_alreadyRunningGTK = gtk_main_level.invokeInt(null) != 0;
|
||||
_isLoaded = true;
|
||||
|
||||
if (GtkEventDispatch.DEBUG) {
|
||||
LoggerFactory.getLogger(GtkLoader.class).debug("GTK: {}", gtk3LibName);
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
if (library != null) {
|
||||
library.close();
|
||||
}
|
||||
|
||||
if (GtkEventDispatch.DEBUG) {
|
||||
LoggerFactory.getLogger(GtkLoader.class).debug("Error loading library.", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// now version 2
|
||||
if (!_isLoaded) {
|
||||
try {
|
||||
library = JNA.register(gtk2LibName, Gtk2.class);
|
||||
|
||||
_isGtk2 = true;
|
||||
major = library.getGlobalVariableAddress("gtk_major_version").getInt(0);
|
||||
minor = library.getGlobalVariableAddress("gtk_minor_version").getInt(0);
|
||||
micro = library.getGlobalVariableAddress("gtk_micro_version").getInt(0);
|
||||
|
||||
gtk_status_icon_position_menu = Function.getFunction(gtk2LibName, "gtk_status_icon_position_menu");
|
||||
Function gtk_main_level = library.getFunction("gtk_main_level");
|
||||
|
||||
// when running inside of JavaFX, this will be '1'. All other times this should be '0'
|
||||
// when it's '1', it means that someone else has started GTK -- so we DO NOT NEED TO.
|
||||
_alreadyRunningGTK = gtk_main_level.invokeInt(null) != 0;
|
||||
_isLoaded = true;
|
||||
if (GtkEventDispatch.DEBUG) {
|
||||
LoggerFactory.getLogger(GtkLoader.class).debug("GTK: {}", gtk2LibName);
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
if (library != null) {
|
||||
library.close();
|
||||
}
|
||||
|
||||
if (GtkEventDispatch.DEBUG) {
|
||||
LoggerFactory.getLogger(GtkLoader.class).debug("Error loading library", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (shouldLoadGtk && _isLoaded) {
|
||||
isLoaded = true;
|
||||
|
||||
// depending on how the system is initialized, SWT may, or may not, have the gtk_main loop running.
|
||||
// It will ALWAYS EVENTUALLY run, so we do not want to run our own GTK event loop. It is also incompatible with our event loop
|
||||
_alreadyRunningGTK |= RenderProvider.alreadyRunning();
|
||||
|
||||
alreadyRunningGTK = _alreadyRunningGTK;
|
||||
isGtk2 = _isGtk2;
|
||||
isGtk3 = !_isGtk2;
|
||||
|
||||
MAJOR = major;
|
||||
MINOR = minor;
|
||||
MICRO = micro;
|
||||
}
|
||||
else {
|
||||
isLoaded = false;
|
||||
|
||||
alreadyRunningGTK = false;
|
||||
isGtk2 = false;
|
||||
isGtk3 = false;
|
||||
|
||||
MAJOR = 0;
|
||||
MINOR = 0;
|
||||
MICRO = 0;
|
||||
}
|
||||
|
||||
// This is so that queries for the GTK version DO NOT try to load GTK
|
||||
GtkCheck.isGtk2 = isGtk2;
|
||||
GtkCheck.isGtk3 = isGtk3;
|
||||
GtkCheck.isGtkLoaded = isLoaded;
|
||||
|
||||
GtkCheck.MAJOR = MAJOR;
|
||||
GtkCheck.MINOR = MINOR;
|
||||
GtkCheck.MICRO = MICRO;
|
||||
|
||||
|
||||
// load any GTK version specific methods
|
||||
if (isGtk3) {
|
||||
Gtk3.loadMethods(library);
|
||||
}
|
||||
|
||||
libraryReference = library;
|
||||
|
||||
if (shouldLoadGtk) {
|
||||
if (!_isLoaded) {
|
||||
throw new RuntimeException("We apologize for this, but we are unable to determine the GTK library is in use, " +
|
||||
"or even if it is in use... Please create an issue for this and include your OS type and configuration.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
package dorkbox.jna.linux;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@SuppressWarnings({"unused", "PointlessBitwiseExpression"})
|
||||
public
|
||||
class GtkState {
|
||||
public static final int NORMAL = 0x0; // normal state.
|
||||
public static final int ACTIVE = 0x1; // pressed-in or activated; e.g. buttons while the mouse button is held down.
|
||||
public static final int PRELIGHT = 0x2; // color when the mouse is over an activatable widget.
|
||||
public static final int SELECTED = 0x3; // color when something is selected, e.g. when selecting some text to cut/copy.
|
||||
public static final int INSENSITIVE = 0x4; // color when the mouse is over an activatable widget.
|
||||
|
||||
public static final int FLAG_NORMAL = 0;
|
||||
public static final int FLAG_ACTIVE = 1 << 0;
|
||||
public static final int FLAG_PRELIGHT = 1 << 1;
|
||||
public static final int FLAG_SELECTED = 1 << 2;
|
||||
public static final int FLAG_INSENSITIVE = 1 << 3;
|
||||
public static final int FLAG_INCONSISTENT = 1 << 4;
|
||||
public static final int FLAG_FOCUSED = 1 << 5;
|
||||
public static final int FLAG_BACKDROP = 1 << 6;
|
||||
}
|
|
@ -0,0 +1,513 @@
|
|||
/*
|
||||
* Copyright 2017 dorkbox, llc
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package dorkbox.jna.linux;
|
||||
|
||||
import static dorkbox.jna.linux.Gtk.Gtk3;
|
||||
import static dorkbox.jna.linux.Gtk2.Gtk2;
|
||||
import static dorkbox.jna.linux.Gtk2.isGtk3;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.Toolkit;
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.sun.jna.Pointer;
|
||||
import com.sun.jna.ptr.PointerByReference;
|
||||
|
||||
import dorkbox.jna.KotlinUtils;
|
||||
import dorkbox.jna.linux.structs.GtkRequisition;
|
||||
import dorkbox.jna.linux.structs.GtkStyle;
|
||||
import dorkbox.jna.linux.structs.PangoRectangle;
|
||||
import dorkbox.os.OS;
|
||||
|
||||
/**
|
||||
* Class to contain all of the various methods needed to get information set by a GTK theme.
|
||||
*/
|
||||
@SuppressWarnings({"unused", "WeakerAccess"})
|
||||
public
|
||||
class GtkTheme {
|
||||
/** Fallback for an unknown tray image size. */
|
||||
public static volatile int TRAY_IMAGE_SIZE_FALLBACK = OS.INSTANCE.getInt(GtkTheme.class.getCanonicalName() + ".TRAY_IMAGE_SIZE_FALLBACK", 24);
|
||||
|
||||
/** Fallback for an unknown tray menu image size. */
|
||||
public static volatile int TRAY_MENU_IMAGE_SIZE_FALLBACK = OS.INSTANCE.getInt(GtkTheme.class.getCanonicalName() + ".TRAY_MENU_IMAGE_SIZE_FALLBACK", 16);
|
||||
|
||||
public static
|
||||
Rectangle getPixelTextHeight(String text) {
|
||||
// the following method requires an offscreen widget to get the size of text (for the checkmark size) via pango
|
||||
// don't forget to destroy everything!
|
||||
Pointer menu = null;
|
||||
Pointer item = null;
|
||||
|
||||
try {
|
||||
menu = Gtk2.gtk_menu_new();
|
||||
item = Gtk2.gtk_image_menu_item_new_with_mnemonic(text);
|
||||
|
||||
Gtk2.gtk_container_add(menu, item);
|
||||
|
||||
Gtk2.gtk_widget_realize(menu);
|
||||
Gtk2.gtk_widget_realize(item);
|
||||
Gtk2.gtk_widget_show_all(menu);
|
||||
|
||||
// get the text widget (GtkAccelLabel/GtkLabel) from inside the GtkMenuItem
|
||||
Pointer textLabel = Gtk2.gtk_bin_get_child(item);
|
||||
Pointer pangoLayout = Gtk2.gtk_label_get_layout(textLabel);
|
||||
|
||||
// ink pixel size is how much exact space it takes on the screen
|
||||
PangoRectangle ink = new PangoRectangle();
|
||||
|
||||
Gtk2.pango_layout_get_pixel_extents(pangoLayout, ink.getPointer(), null);
|
||||
ink.read();
|
||||
|
||||
return new Rectangle(ink.width, ink.height);
|
||||
} finally {
|
||||
Gtk2.gtk_widget_destroy(item);
|
||||
Gtk2.gtk_widget_destroy(menu);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the size of the GTK menu entry's IMAGE, as best as we can tell, for determining how large of icons to use for the menu entry
|
||||
*/
|
||||
public static
|
||||
int getMenuEntryImageSize() {
|
||||
final AtomicReference<Integer> imageHeight = new AtomicReference<>();
|
||||
|
||||
GtkEventDispatch.dispatchAndWait(()->{
|
||||
Pointer offscreen = Gtk2.gtk_offscreen_window_new();
|
||||
|
||||
// get the default icon size for the "paste" icon.
|
||||
Pointer item = null;
|
||||
|
||||
try {
|
||||
item = Gtk2.gtk_image_menu_item_new_from_stock("gtk-paste", null);
|
||||
|
||||
// make sure the image is shown (sometimes it's not always shown, then height is 0)
|
||||
Gtk2.gtk_image_menu_item_set_always_show_image(item, true);
|
||||
|
||||
Gtk2.gtk_container_add(offscreen, item);
|
||||
Gtk2.gtk_widget_realize(offscreen);
|
||||
Gtk2.gtk_widget_realize(item);
|
||||
Gtk2.gtk_widget_show_all(item);
|
||||
|
||||
PointerByReference r = new PointerByReference();
|
||||
GObject.g_object_get(item, "image", r.getPointer(), null);
|
||||
|
||||
Pointer imageWidget = r.getValue();
|
||||
|
||||
GtkRequisition gtkRequisition = new GtkRequisition();
|
||||
Gtk2.gtk_widget_size_request(imageWidget, gtkRequisition.getPointer());
|
||||
gtkRequisition.read();
|
||||
|
||||
imageHeight.set(gtkRequisition.height);
|
||||
} finally {
|
||||
if (item != null) {
|
||||
Gtk2.gtk_widget_destroy(item);
|
||||
Gtk2.gtk_widget_destroy(offscreen);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
int height = imageHeight.get();
|
||||
if (height > 0) {
|
||||
return height;
|
||||
}
|
||||
|
||||
LoggerFactory.getLogger(GtkTheme.class).warn("Unable to get tray menu image size. Using fallback: " + TRAY_MENU_IMAGE_SIZE_FALLBACK);
|
||||
return TRAY_MENU_IMAGE_SIZE_FALLBACK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the system tray indicator size.
|
||||
* - AppIndicator: will properly scale the image if it's not the correct size
|
||||
* - GtkStatusIndicator: ??
|
||||
*/
|
||||
public static
|
||||
int getIndicatorSize() {
|
||||
// Linux is similar enough, that it just uses this method
|
||||
// https://wiki.archlinux.org/index.php/HiDPI
|
||||
|
||||
// 96 DPI is the default
|
||||
final double defaultDPI = 96.0;
|
||||
|
||||
final AtomicReference<Double> screenScale = new AtomicReference<>();
|
||||
final AtomicInteger screenDPI = new AtomicInteger();
|
||||
screenScale.set(0D);
|
||||
screenDPI.set(0);
|
||||
|
||||
GtkEventDispatch.dispatchAndWait(()->{
|
||||
// screen DPI
|
||||
Pointer screen = Gtk2.gdk_screen_get_default();
|
||||
if (screen != null) {
|
||||
// this call makes NO SENSE, but reading the documentation shows it is the CORRECT call.
|
||||
screenDPI.set((int) Gtk2.gdk_screen_get_resolution(screen));
|
||||
}
|
||||
|
||||
if (isGtk3) {
|
||||
Pointer window = Gtk2.gdk_get_default_root_window();
|
||||
if (window != null) {
|
||||
double scale = Gtk3.gdk_window_get_scale_factor(window);
|
||||
screenScale.set(scale);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// fallback
|
||||
if (screenDPI.get() <= 0) {
|
||||
// GET THE DPI IN LINUX
|
||||
// https://wiki.archlinux.org/index.php/Talk:GNOME
|
||||
Object detectedValue = Toolkit.getDefaultToolkit().getDesktopProperty("gnome.Xft/DPI");
|
||||
if (detectedValue instanceof Integer) {
|
||||
int asInteger = (Integer) detectedValue;
|
||||
// reasonably safe check
|
||||
if (asInteger > 1024) {
|
||||
int dpi = asInteger / 1024;
|
||||
screenDPI.set(dpi);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 50 dpi is the minimum value gnome allows, and assume something screwed up. We apply this for ALL environments!
|
||||
if (screenDPI.get() < 50) {
|
||||
screenDPI.set((int) defaultDPI);
|
||||
}
|
||||
|
||||
|
||||
// check system ENV variables.
|
||||
if (screenScale.get() == 0) {
|
||||
String envVar = System.getenv("QT_AUTO_SCREEN_SCALE_FACTOR");
|
||||
if (envVar != null) {
|
||||
try {
|
||||
screenScale.set(Double.parseDouble(envVar));
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// check system ENV variables.
|
||||
if (screenScale.get() == 0) {
|
||||
String envVar = System.getenv("QT_SCALE_FACTOR");
|
||||
if (envVar != null) {
|
||||
try {
|
||||
screenScale.set(Double.parseDouble(envVar));
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// check system ENV variables.
|
||||
if (screenScale.get() == 0) {
|
||||
String envVar = System.getenv("GDK_SCALE");
|
||||
if (envVar != null) {
|
||||
try {
|
||||
screenScale.set(Double.parseDouble(envVar));
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// check system ENV variables.
|
||||
if (screenScale.get() == 0) {
|
||||
String envVar = System.getenv("ELM_SCALE");
|
||||
if (envVar != null) {
|
||||
try {
|
||||
screenScale.set(Double.parseDouble(envVar));
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
OS.DesktopEnv.Env env = OS.DesktopEnv.INSTANCE.getEnv();
|
||||
|
||||
// sometimes the scaling-factor is set. If we have gsettings, great! otherwise try KDE
|
||||
try {
|
||||
// gsettings get org.gnome.desktop.interface scaling-factor
|
||||
String output = KotlinUtils.INSTANCE.execute("gsettings", "get", "org.gnome.desktop.interface", "scaling-factor");
|
||||
|
||||
if (!output.isEmpty() && !output.endsWith("not found")) {
|
||||
// DEFAULT icon size is 16. HiDpi changes this scale, so we should use it as well.
|
||||
// should be: uint32 0 or something
|
||||
if (output.contains("uint32")) {
|
||||
String value = output.substring(output.indexOf("uint") + 7);
|
||||
|
||||
// 0 is disabled (no scaling)
|
||||
// 1 is enabled (default scale)
|
||||
// 2 is 2x scale
|
||||
// 3 is 3x scale
|
||||
// etc
|
||||
|
||||
double scalingFactor = Double.parseDouble(value);
|
||||
if (scalingFactor >= 1) {
|
||||
screenScale.set(scalingFactor);
|
||||
}
|
||||
|
||||
// A setting of 2, 3, etc, which is all you can do with scaling-factor
|
||||
// To enable HiDPI, use gsettings:
|
||||
// gsettings set org.gnome.desktop.interface scaling-factor 2
|
||||
}
|
||||
}
|
||||
} catch (Throwable ignore) {
|
||||
}
|
||||
|
||||
if (OS.DesktopEnv.INSTANCE.isKDE()) {
|
||||
// check the custom KDE override file
|
||||
try {
|
||||
File customSettings = new File("/usr/bin/startkde-custom");
|
||||
if (customSettings.canRead()) {
|
||||
List<String> lines = KotlinUtils.INSTANCE.readLines(customSettings);
|
||||
for (String line : lines) {
|
||||
String str = "export GDK_SCALE=";
|
||||
int i = line.indexOf(str);
|
||||
if (i > -1) {
|
||||
String scale = line.substring(i + str.length());
|
||||
double scalingFactor = Double.parseDouble(scale);
|
||||
if (scalingFactor >= 1) {
|
||||
screenScale.set(scalingFactor);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
|
||||
|
||||
// System.err.println("screen scale: " + screenScale.get());
|
||||
// System.err.println("screen DPI: " + screenDPI.get());
|
||||
|
||||
if (screenScale.get() == 0) {
|
||||
/*
|
||||
*
|
||||
* Looking in plasma-framework/src/declarativeimports/core/units.cpp:
|
||||
// Scale the icon sizes up using the devicePixelRatio
|
||||
// This function returns the next stepping icon size
|
||||
// and multiplies the global settings with the dpi ratio.
|
||||
const qreal ratio = devicePixelRatio();
|
||||
|
||||
if (ratio < 1.5) {
|
||||
return size;
|
||||
} else if (ratio < 2.0) {
|
||||
return size * 1.5;
|
||||
} else if (ratio < 2.5) {
|
||||
return size * 2.0;
|
||||
} else if (ratio < 3.0) {
|
||||
return size * 2.5;
|
||||
} else if (ratio < 3.5) {
|
||||
return size * 3.0;
|
||||
} else {
|
||||
return size * ratio;
|
||||
}
|
||||
My ratio is 1.47674, that means I have no scaling at all when there is a 1.5 factor existing. Is it reasonable? Wouldn't it make more sense to use the factor the closest to the ratio rather than what is done here?
|
||||
*/
|
||||
|
||||
File mainFile = new File("/usr/share/plasma/plasmoids/org.kde.plasma.private.systemtray/contents/config/main.xml");
|
||||
if (mainFile.canRead()) {
|
||||
List<String> lines = KotlinUtils.INSTANCE.readLines(mainFile);
|
||||
boolean found = false;
|
||||
int index;
|
||||
for (final String line : lines) {
|
||||
if (line.contains("<entry name=\"iconSize\" type=\"Int\">")) {
|
||||
found = true;
|
||||
// have to get the "default" line value
|
||||
}
|
||||
|
||||
String str = "<default>";
|
||||
if (found && (index = line.indexOf(str)) > -1) {
|
||||
// this is our line. now get the value.
|
||||
String substring = line.substring(index + str.length(), line.indexOf("</default>", index));
|
||||
|
||||
// Default icon size for the systray icons, it's an enum which values mean,
|
||||
// Small, SmallMedium, Medium, Large, Huge, Enormous respectively.
|
||||
// On low DPI systems they correspond to :
|
||||
// 16, 22, 32, 48, 64, 128 pixels.
|
||||
// On high DPI systems those values would be scaled up, depending on the DPI.
|
||||
int imageSize = 0;
|
||||
Integer imageSizeEnum = KotlinUtils.INSTANCE.toInteger(substring);
|
||||
if (imageSizeEnum != null) {
|
||||
switch (imageSizeEnum) {
|
||||
case 0:
|
||||
imageSize = 16;
|
||||
break;
|
||||
case 1:
|
||||
imageSize = 22;
|
||||
break;
|
||||
case 2:
|
||||
imageSize = 32;
|
||||
break;
|
||||
case 3:
|
||||
imageSize = 48;
|
||||
break;
|
||||
case 4:
|
||||
imageSize = 64;
|
||||
break;
|
||||
case 5:
|
||||
imageSize = 128;
|
||||
break;
|
||||
}
|
||||
|
||||
if (imageSize > 0) {
|
||||
double scaleRatio = screenDPI.get() / defaultDPI;
|
||||
|
||||
return (int) (scaleRatio * imageSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (OS.Linux.INSTANCE.isUbuntu() && OS.DesktopEnv.INSTANCE.isUnity(env)) {
|
||||
// if we measure on ubuntu unity using a screen shot (using swing, so....) , the max size was 24, HOWEVER this goes from
|
||||
// the top->bottom of the indicator bar -- and since it was swing, it uses a different rendering method and it (honestly)
|
||||
// looks weird, because there is no padding for the icon. The official AppIndicator size is hardcoded...
|
||||
// http://bazaar.launchpad.net/~indicator-applet-developers/libindicator/trunk.16.10/view/head:/libindicator/indicator-image-helper.c
|
||||
|
||||
return 22;
|
||||
}
|
||||
|
||||
if (env == OS.DesktopEnv.Env.XFCE) {
|
||||
// xfce is easy, because it's not a GTK setting for the size (xfce notification area maximum icon size)
|
||||
String properties = OS.DesktopEnv.INSTANCE.queryXfce("xfce4-panel", null);
|
||||
String[] propertiesAsList = properties.split(OS.INSTANCE.getLINE_SEPARATOR());
|
||||
for (String prop : propertiesAsList) {
|
||||
if (prop.startsWith("/plugins/") && prop.endsWith("/size-max")) {
|
||||
// this is the property we are looking for (we just don't know which panel it's on)
|
||||
// note: trim() is required because it will strip new-line
|
||||
|
||||
// xfconf-query -c xfce4-panel -p /plugins/plugin-14 (this will say 'systray' or 'tasklist' or whatever)
|
||||
// find the 'systray' plugin
|
||||
String panelString = prop.substring(0, prop.indexOf("/size-max"));
|
||||
String panelName = OS.DesktopEnv.INSTANCE.queryXfce("xfce4-panel", panelString).trim();
|
||||
if (panelName.equals("systray")) {
|
||||
String size = OS.DesktopEnv.INSTANCE.queryXfce("xfce4-panel", prop).trim();
|
||||
try {
|
||||
return Integer.parseInt(size);
|
||||
} catch (Exception e) {
|
||||
LoggerFactory.getLogger(GtkTheme.class)
|
||||
.error("Unable to get XFCE notification panel size for channel '{}', property '{}'",
|
||||
"xfce4-panel", prop, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// try to use GTK to get the tray icon size
|
||||
final AtomicInteger traySize = new AtomicInteger();
|
||||
GtkEventDispatch.dispatchAndWait(()->{
|
||||
Pointer screen = Gtk2.gdk_screen_get_default();
|
||||
Pointer settings = null;
|
||||
|
||||
if (screen != null) {
|
||||
settings = Gtk2.gtk_settings_get_for_screen(screen);
|
||||
}
|
||||
|
||||
if (settings != null) {
|
||||
PointerByReference pointer = new PointerByReference();
|
||||
|
||||
// https://wiki.archlinux.org/index.php/GTK%2B
|
||||
// To use smaller icons, use a line like this:
|
||||
// gtk-icon-sizes = "panel-menu=16,16:panel=16,16:gtk-menu=16,16:gtk-large-toolbar=16,16:gtk-small-toolbar=16,16:gtk-button=16,16"
|
||||
|
||||
// this gets icon sizes. On XFCE, ubuntu, it returns "panel-menu-bar=24,24"
|
||||
// NOTE: gtk-icon-sizes is deprecated and ignored since GTK+ 3.10.
|
||||
|
||||
// A list of icon sizes. The list is separated by colons, and item has the form: size-name = width , height
|
||||
GObject.g_object_get(settings, "gtk-icon-sizes", pointer.getPointer(), null);
|
||||
Pointer value = pointer.getValue();
|
||||
if (value != null) {
|
||||
// this might be null for later versions of GTK!
|
||||
String iconSizes = value.getString(0);
|
||||
String[] strings = new String[] {"panel-menu-bar=", "panel=", "gtk-large-toolbar=", "gtk-small-toolbar="};
|
||||
for (String var : strings) {
|
||||
int i = iconSizes.indexOf(var);
|
||||
if (i >= 0) {
|
||||
String size = iconSizes.substring(i + var.length(), iconSizes.indexOf(",", i));
|
||||
|
||||
Integer sizeInt = KotlinUtils.INSTANCE.toInteger(size);
|
||||
if (sizeInt != null) {
|
||||
traySize.set(sizeInt);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
int i = traySize.get();
|
||||
if (i != 0) {
|
||||
return i;
|
||||
}
|
||||
|
||||
// sane default
|
||||
LoggerFactory.getLogger(GtkTheme.class).warn("Unable to get tray image size. Using fallback: " + TRAY_IMAGE_SIZE_FALLBACK);
|
||||
return TRAY_IMAGE_SIZE_FALLBACK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the widget color of text for the current theme, or black. It is important that this is called AFTER GTK has been initialized.
|
||||
*/
|
||||
public static
|
||||
Color getTextColor() {
|
||||
final AtomicReference<Color> color = new AtomicReference<>(null);
|
||||
GtkEventDispatch.dispatchAndWait(()->{
|
||||
Color c;
|
||||
|
||||
// the following method requires an offscreen widget to get the style information from.
|
||||
// don't forget to destroy everything!
|
||||
Pointer menu = null;
|
||||
Pointer item = null;
|
||||
|
||||
try {
|
||||
menu = Gtk2.gtk_menu_new();
|
||||
item = Gtk2.gtk_image_menu_item_new_with_mnemonic("a");
|
||||
|
||||
Gtk2.gtk_container_add(menu, item);
|
||||
|
||||
Gtk2.gtk_widget_realize(menu);
|
||||
Gtk2.gtk_widget_realize(item);
|
||||
Gtk2.gtk_widget_show_all(menu);
|
||||
|
||||
GtkStyle style = Gtk2.gtk_rc_get_style(item);
|
||||
style.read();
|
||||
|
||||
// this is the same color chromium uses (fg)
|
||||
// https://chromium.googlesource.com/chromium/src/+/b3ca230ddd7d1238ee96ed26ea23e369f10dd655/chrome/browser/ui/libgtk2ui/gtk2_ui.cc#873
|
||||
c = style.fg[GtkState.NORMAL].getColor();
|
||||
|
||||
color.set(c);
|
||||
} finally {
|
||||
Gtk2.gtk_widget_destroy(item);
|
||||
Gtk2.gtk_widget_destroy(menu);
|
||||
}
|
||||
});
|
||||
|
||||
return color.get();
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
/*
|
||||
* Copyright 2021 dorkbox, llc
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package dorkbox.jna.linux;
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* Copyright 2015 dorkbox, llc
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package dorkbox.jna.linux.structs;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import com.sun.jna.Pointer;
|
||||
import com.sun.jna.Structure;
|
||||
|
||||
import dorkbox.jna.linux.AppIndicator;
|
||||
|
||||
public
|
||||
class AppIndicatorInstanceStruct extends Structure {
|
||||
public GObjectStruct parent;
|
||||
public Pointer priv;
|
||||
|
||||
@Override
|
||||
protected
|
||||
List<String> getFieldOrder() {
|
||||
return Arrays.asList("parent", "priv");
|
||||
}
|
||||
|
||||
public
|
||||
void app_indicator_set_title(String title) {
|
||||
AppIndicator.app_indicator_set_title(getPointer(), title);
|
||||
}
|
||||
|
||||
public
|
||||
void app_indicator_set_status(int status) {
|
||||
AppIndicator.app_indicator_set_status(getPointer(), status);
|
||||
}
|
||||
|
||||
public
|
||||
void app_indicator_set_menu(Pointer menu) {
|
||||
AppIndicator.app_indicator_set_menu(getPointer(), menu);
|
||||
}
|
||||
|
||||
public
|
||||
void app_indicator_set_icon(String icon_name) {
|
||||
AppIndicator.app_indicator_set_icon(getPointer(), icon_name);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* Copyright 2015 dorkbox, llc
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package dorkbox.jna.linux.structs;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import com.sun.jna.Pointer;
|
||||
import com.sun.jna.Structure;
|
||||
|
||||
public
|
||||
class GObjectStruct extends Structure {
|
||||
public
|
||||
class ByValue extends GObjectStruct implements Structure.ByValue {}
|
||||
|
||||
|
||||
public
|
||||
class ByReference extends GObjectStruct implements Structure.ByReference {}
|
||||
|
||||
|
||||
public GTypeInstanceStruct g_type_instance;
|
||||
public int ref_count;
|
||||
public Pointer qdata;
|
||||
|
||||
@Override
|
||||
protected
|
||||
List<String> getFieldOrder() {
|
||||
return Arrays.asList("g_type_instance", "ref_count", "qdata");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* Copyright 2015 dorkbox, llc
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package dorkbox.jna.linux.structs;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import com.sun.jna.Pointer;
|
||||
import com.sun.jna.Structure;
|
||||
|
||||
public
|
||||
class GTypeInstanceStruct extends Structure {
|
||||
public
|
||||
class ByValue extends GTypeInstanceStruct implements Structure.ByValue {}
|
||||
|
||||
|
||||
public
|
||||
class ByReference extends GTypeInstanceStruct implements Structure.ByReference {}
|
||||
|
||||
|
||||
public Pointer g_class;
|
||||
|
||||
@Override
|
||||
protected
|
||||
List<String> getFieldOrder() {
|
||||
return Arrays.asList("g_class");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
* Copyright 2017 dorkbox, llc
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package dorkbox.jna.linux.structs;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import com.sun.jna.Structure;
|
||||
|
||||
/**
|
||||
* https://developer.gnome.org/gdk3/stable/gdk3-Colors.html
|
||||
*
|
||||
* GdkColor has been deprecated since version 3.14 and should not be used in newly-written code.
|
||||
*/
|
||||
public
|
||||
class GdkColor extends Structure {
|
||||
|
||||
/* The color type.
|
||||
* A color consists of red, green and blue values in the
|
||||
* range 0-65535 and a pixel value. The pixel value is highly
|
||||
* dependent on the depth and colormap which this color will
|
||||
* be used to draw into. Therefore, sharing colors between
|
||||
* colormaps is a bad idea.
|
||||
*/
|
||||
public int pixel;
|
||||
public short red;
|
||||
public short green;
|
||||
public short blue;
|
||||
|
||||
/**
|
||||
* Convert from positive int (value between 0 and 65535, these are 16 bits per pixel) to values from 0-255
|
||||
*/
|
||||
private static int convert(int inputColor) {
|
||||
return (inputColor & 0x0000FFFF >> 8) & 0xFF;
|
||||
}
|
||||
|
||||
public int red() {
|
||||
return convert(red);
|
||||
}
|
||||
|
||||
public int green() {
|
||||
return convert(green);
|
||||
}
|
||||
|
||||
public int blue() {
|
||||
return convert(blue);
|
||||
}
|
||||
|
||||
public
|
||||
Color getColor() {
|
||||
read(); // have to read the struct members first!
|
||||
return new Color(red(), green(), blue());
|
||||
}
|
||||
|
||||
@Override
|
||||
public
|
||||
String toString() {
|
||||
return "[r=" + red() + ",g=" + green() + ",b=" + blue() + "]";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected
|
||||
List<String> getFieldOrder() {
|
||||
return Arrays.asList("pixel", "red", "green", "blue");
|
||||
}
|
||||
|
||||
|
||||
public
|
||||
class ByValue extends GdkColor implements Structure.ByValue {}
|
||||
|
||||
|
||||
public static
|
||||
class ByReference extends GdkColor implements Structure.ByReference {}
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* Copyright 2015 dorkbox, llc
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package dorkbox.jna.linux.structs;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import com.sun.jna.Pointer;
|
||||
import com.sun.jna.Structure;
|
||||
|
||||
public
|
||||
class GdkEventButton extends Structure {
|
||||
public int type;
|
||||
public Pointer window;
|
||||
public int send_event;
|
||||
public int time;
|
||||
public double x;
|
||||
public double y;
|
||||
public Pointer axes;
|
||||
public int state;
|
||||
public int button;
|
||||
public Pointer device;
|
||||
public double x_root;
|
||||
public double y_root;
|
||||
|
||||
@Override
|
||||
protected
|
||||
List<String> getFieldOrder() {
|
||||
return Arrays.asList("type", "window", "send_event", "time", "x", "y", "axes", "state", "button", "device", "x_root", "y_root");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Copyright 2017 dorkbox, llc
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package dorkbox.jna.linux.structs;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import com.sun.jna.Structure;
|
||||
|
||||
/**
|
||||
* https://developer.gimp.org/api/2.0/gtk/GtkWidget.html#GtkRequisition
|
||||
*/
|
||||
public
|
||||
class GtkRequisition extends Structure {
|
||||
|
||||
public int width;
|
||||
public int height;
|
||||
|
||||
@Override
|
||||
protected
|
||||
List<String> getFieldOrder() {
|
||||
return Arrays.asList("width", "height");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,113 @@
|
|||
/*
|
||||
* Copyright 2017 dorkbox, llc
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package dorkbox.jna.linux.structs;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import com.sun.jna.Pointer;
|
||||
import com.sun.jna.Structure;
|
||||
|
||||
public
|
||||
class GtkStyle extends Structure {
|
||||
/*
|
||||
* There are several 'directives' to change the attributes of a widget.
|
||||
* fg - Sets the foreground color of a widget.
|
||||
* bg - Sets the background color of a widget.
|
||||
* text - Sets the foreground color for widgets that have editable text.
|
||||
* base - Sets the background color for widgets that have editable text.
|
||||
* bg_pixmap - Sets the background of a widget to a tiled pixmap.
|
||||
* font_name - Sets the font to be used with the given widget.
|
||||
* xthickness - Sets the left and right border width. This is not what you might think; it sets the borders of children(?)
|
||||
* ythickness - similar to above but for the top and bottom.
|
||||
*
|
||||
* There are several states a widget can be in, and you can set different colors, pixmaps and fonts for each state. These states are:
|
||||
* NORMAL - The normal state of a widget. Ie the mouse is not over it, and it is not being pressed, etc.
|
||||
* PRELIGHT - When the mouse is over top of the widget, colors defined using this state will be in effect.
|
||||
* ACTIVE - When the widget is pressed or clicked it will be active, and the attributes assigned by this tag will be in effect.
|
||||
* INSENSITIVE - This is the state when a widget is 'greyed out'. It is not active, and cannot be clicked on.
|
||||
* SELECTED - When an object is selected, it takes these attributes.
|
||||
*/
|
||||
|
||||
public static
|
||||
class ByReference extends GtkStyle implements Structure.ByReference {
|
||||
}
|
||||
|
||||
public
|
||||
class ByValue extends GtkStyle implements Structure.ByValue {
|
||||
}
|
||||
|
||||
// required, even though it's "private" in the corresponding C code. OTHERWISE the memory offsets are INCORRECT.
|
||||
public GObjectStruct parent_instance;
|
||||
|
||||
/** fg: foreground for drawing GtkLabel */
|
||||
public GdkColor fg[] = new GdkColor[5];
|
||||
|
||||
/** bg: the usual background color, gray by default */
|
||||
public GdkColor bg[] = new GdkColor[5];
|
||||
|
||||
public GdkColor light[] = new GdkColor[5];
|
||||
public GdkColor dark[] = new GdkColor[5];
|
||||
public GdkColor mid[] = new GdkColor[5];
|
||||
|
||||
/**
|
||||
* text: text for entries and text widgets (although in GTK 1.2 sometimes fg gets used, this is more or less a bug and fixed in GTK 2.0).
|
||||
*/
|
||||
public GdkColor text[] = new GdkColor[5];
|
||||
|
||||
/** base: background when using text, colored white in the default theme. */
|
||||
public GdkColor base[] = new GdkColor[5];
|
||||
|
||||
/** Halfway between text/base */
|
||||
public GdkColor text_aa[] = new GdkColor[5];
|
||||
|
||||
public GdkColor black;
|
||||
public GdkColor white;
|
||||
public Pointer /*PangoFontDescription*/ font_desc;
|
||||
public int xthickness;
|
||||
public int ythickness;
|
||||
public Pointer /*cairo_pattern_t*/ background[] = new Pointer[5];
|
||||
|
||||
public
|
||||
void debug(final int gtkState) {
|
||||
System.err.println("base " + base[gtkState].getColor());
|
||||
System.err.println("text " + text[gtkState].getColor());
|
||||
System.err.println("text_aa " + text_aa[gtkState].getColor());
|
||||
System.err.println("bg " + bg[gtkState].getColor());
|
||||
System.err.println("fg " + fg[gtkState].getColor());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected
|
||||
List<String> getFieldOrder() {
|
||||
return Arrays.asList("parent_instance",
|
||||
"fg",
|
||||
"bg",
|
||||
"light",
|
||||
"dark",
|
||||
"mid",
|
||||
"text",
|
||||
"base",
|
||||
"text_aa",
|
||||
"black",
|
||||
"white",
|
||||
"font_desc",
|
||||
"xthickness",
|
||||
"ythickness",
|
||||
"background");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Copyright 2017 dorkbox, llc
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package dorkbox.jna.linux.structs;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import com.sun.jna.Structure;
|
||||
|
||||
/**
|
||||
* https://developer.gnome.org/pango/stable/pango-Glyph-Storage.html#PangoRectangle
|
||||
*/
|
||||
public
|
||||
class PangoRectangle extends Structure {
|
||||
|
||||
public int x;
|
||||
public int y;
|
||||
public int width;
|
||||
public int height;
|
||||
|
||||
@Override
|
||||
protected
|
||||
List<String> getFieldOrder() {
|
||||
return Arrays.asList("x", "y", "width", "height");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,184 @@
|
|||
/*
|
||||
* Copyright 2010 dorkbox, llc
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package dorkbox.jna.linux.structs;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import com.sun.jna.Structure;
|
||||
|
||||
@SuppressWarnings("ALL")
|
||||
public
|
||||
class Termios extends Structure {
|
||||
// NOTE: MUST BE BITS!! from: /usr/include/x86_64-linux-gnu/bits/termios.h
|
||||
// the one in octal WILL NOT WORK!! (you have been warned)
|
||||
|
||||
// Definitions at: http://linux.die.net/man/3/termios
|
||||
|
||||
// Input flags - software input processing
|
||||
public static class Input {
|
||||
public static final int IGNBRK = 0000001; // ignore BREAK condition
|
||||
public static final int BRKINT = 0000002; // map BREAK to SIGINTR
|
||||
public static final int IGNPAR = 0000004; // ignore (discard) parity errors
|
||||
public static final int PARMRK = 0000010; // mark parity and framing errors
|
||||
public static final int INPCK = 0000020; // enable checking of parity errors
|
||||
public static final int ISTRIP = 0000040; // strip 8th bit off chars
|
||||
public static final int INLCR = 0000100; // map NL into CR
|
||||
public static final int IGNCR = 0000200; // ignore CR
|
||||
public static final int ICRNL = 0000400; // map CR to NL (ala CRMOD)
|
||||
// public static final int IUCLC = 0001000; // (not in POSIX) Map uppercase characters to lowercase on input.
|
||||
public static final int IXON = 0002000; // enable output flow control
|
||||
public static final int IXANY = 0004000; // any char will restart after stop
|
||||
public static final int IXOFF = 0010000; // enable input flow control
|
||||
public static final int IMAXBEL = 0020000; // ring bell on input queue full
|
||||
// public static final int IUTF8 = 0040000; // (since Linux 2.6.4) (not in POSIX) Input is UTF8; this allows character-erase to be correctly performed in cooked mode.
|
||||
}
|
||||
|
||||
public static class Output {
|
||||
// Output flags - software output processing
|
||||
public static final int OPOST = 0000001; // enable following output processing (not set = raw output)
|
||||
// public static final int OLCUC = 0000002; // (not in POSIX) Map lowercase characters to uppercase on output.
|
||||
public static final int ONLCR = 0000004; // map NL to CR-NL (ala CRMOD)
|
||||
public static final int OCRNL = 0000010; // map CR to NL on output
|
||||
public static final int ONOCR = 0000020; // no CR output at column 0
|
||||
public static final int ONLRET = 0000040; // NL performs CR function
|
||||
public static final int OFILL = 0000100; // Send fill characters for a delay, rather than using a timed delay.
|
||||
public static final int OFDEL = 0000200; // Fill character is ASCII DEL (0177). If unset, fill character is ASCII NUL ('\0'). (Not implemented on Linux.)
|
||||
}
|
||||
|
||||
|
||||
public static class Control {
|
||||
// Control flags - hardware control of terminal
|
||||
public static final int CSIZE = 0000060; // character size mask
|
||||
public static final int CS5 = 0000000; // 5 bits (pseudo)
|
||||
public static final int CS6 = 0000020; // 6 bits
|
||||
public static final int CS7 = 0000040; // 7 bits
|
||||
public static final int CS8 = 0000060; // 8 bits
|
||||
public static final int CSTOPB = 0000100; // send 2 stop bits
|
||||
public static final int CREAD = 0000200; // enable receiver
|
||||
public static final int PARENB = 0000400; // parity enable
|
||||
public static final int PARODD = 0001000; // odd parity, else even
|
||||
public static final int HUPCL = 0002000; // hang up on last close
|
||||
public static final int CLOCAL = 0004000; // ignore modem status lines
|
||||
}
|
||||
|
||||
|
||||
public static class Local {
|
||||
// "Local" flags - dumping ground for other state
|
||||
// Warning: some flags in this structure begin with the letter "I" and look like they belong in the input flag.
|
||||
public static final int ISIG = 0000001; // enable signals INTR, QUIT, [D]SUSP
|
||||
public static final int ICANON = 0000002; // canonicalize input lines
|
||||
//public static final int XCASE = 0000004; // (not in POSIX; not supported under Linux)
|
||||
public static final int ECHO = 0000010; // enable echoing
|
||||
public static final int ECHOE = 0000020; // visually erase chars
|
||||
public static final int ECHOK = 0000040; // echo NL after line kill
|
||||
public static final int ECHONL = 0000100; // echo NL even if ECHO is off
|
||||
public static final int NOFLSH = 0000200; // don't flush after interrupt
|
||||
public static final int TOSTOP = 0000400; // stop background jobs from output
|
||||
public static final int ECHOCTL = 0001000; // echo control chars as ^(Char)
|
||||
public static final int ECHOPRT = 0002000; // visual erase mode for hardcopy
|
||||
public static final int ECHOKE = 0004000; // visual erase for line kill
|
||||
public static final int FLUSHO = 0001000; // output being flushed (state)
|
||||
public static final int PENDIN = 0004000; // XXX retype pending input (state)
|
||||
public static final int IEXTEN = 0100000; // enable DISCARD and LNEXT
|
||||
public static final int EXTPROC = 0200000; // external processing
|
||||
}
|
||||
|
||||
|
||||
public static class ControlChars {
|
||||
// Special Control Characters
|
||||
//
|
||||
// the value is the index into c_cc[] character array.
|
||||
public static final int VINTR = 0; // ISIG
|
||||
public static final int VQUIT = 1; // ISIG
|
||||
public static final int VERASE = 2; // ICANON
|
||||
public static final int VKILL = 3; // ICANON
|
||||
public static final int VEOF = 4; // ICANON
|
||||
public static final int VTIME = 5; // !ICANON
|
||||
public static final int VMIN = 6; // !ICANON
|
||||
public static final int VSWTC = 7;
|
||||
public static final int VSTART = 8; // IXON, IXOFF
|
||||
public static final int VSTOP = 9; // IXON, IXOFF
|
||||
public static final int VSUSP = 10;// ISIG
|
||||
public static final int VEOL = 11;// ICANON
|
||||
public static final int VREPRINT = 12;// ICANON together with IEXTEN
|
||||
public static final int VDISCARD = 13;
|
||||
public static final int VWERASE = 14;// ICANON together with IEXTEN
|
||||
public static final int VLNEXT = 15;// IEXTEN
|
||||
public static final int VEOL2 = 16;// ICANON together with IEXTEN
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public static final int TCSANOW = 0;
|
||||
|
||||
/**
|
||||
* input mode flags
|
||||
*/
|
||||
public int inputFlags;
|
||||
|
||||
/**
|
||||
* output mode flags
|
||||
*/
|
||||
public int outputFlags;
|
||||
|
||||
/**
|
||||
* control mode flags
|
||||
*/
|
||||
public int controlFlags;
|
||||
|
||||
/**
|
||||
* local mode flags
|
||||
*/
|
||||
public int localFlags;
|
||||
|
||||
/**
|
||||
* line discipline
|
||||
*/
|
||||
public char lineDiscipline;
|
||||
|
||||
/**
|
||||
* control characters
|
||||
*/
|
||||
public byte[] controlChars = new byte[32];
|
||||
|
||||
/**
|
||||
* input speed
|
||||
*/
|
||||
public int inputSpeed;
|
||||
|
||||
/**
|
||||
* output speed
|
||||
*/
|
||||
public int outputSpeed;
|
||||
|
||||
public
|
||||
Termios() {}
|
||||
|
||||
@Override
|
||||
protected
|
||||
List<String> getFieldOrder() {
|
||||
return Arrays.asList("inputFlags",
|
||||
"outputFlags",
|
||||
"controlFlags",
|
||||
"localFlags",
|
||||
"lineDiscipline",
|
||||
"controlChars",
|
||||
"inputSpeed",
|
||||
"outputSpeed");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
/*
|
||||
* Copyright 2021 dorkbox, llc
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package dorkbox.jna.linux.structs;
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* Copyright 2018 dorkbox, llc
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package dorkbox.jna.macos.cocoa;
|
||||
|
||||
/**
|
||||
* https://developer.apple.com/documentation/appkit/nscell?language=objc
|
||||
*/
|
||||
public
|
||||
interface NSCellStateValue {
|
||||
int NSMixedState = -1;
|
||||
int NSOffState = 0;
|
||||
int NSOnState = 1;
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Copyright 2018 dorkbox, llc
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package dorkbox.jna.macos.cocoa;
|
||||
|
||||
import com.sun.jna.Pointer;
|
||||
|
||||
import dorkbox.jna.macos.foundation.ObjectiveC;
|
||||
|
||||
/**
|
||||
* https://developer.apple.com/documentation/foundation/nsdata?language=objc
|
||||
*/
|
||||
public
|
||||
class NSData extends NSObject {
|
||||
|
||||
private static final Pointer objectClass = ObjectiveC.objc_lookUpClass("NSData");
|
||||
|
||||
private static final Pointer dataWithBytesLength = ObjectiveC.sel_getUid("dataWithBytes:length:");
|
||||
|
||||
public
|
||||
NSData(byte[] data) {
|
||||
super(ObjectiveC.objc_msgSend(objectClass, dataWithBytesLength, data, data.length));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
* Copyright 2018 dorkbox, llc
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package dorkbox.jna.macos.cocoa;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
|
||||
import com.sun.jna.Pointer;
|
||||
|
||||
import dorkbox.jna.macos.foundation.ObjectiveC;
|
||||
|
||||
|
||||
/**
|
||||
* https://developer.apple.com/documentation/appkit/nsimage?language=objc
|
||||
*/
|
||||
public
|
||||
class NSImage extends NSObject {
|
||||
|
||||
private static final Pointer objectClass = ObjectiveC.objc_lookUpClass("NSImage");
|
||||
|
||||
private static final Pointer initWithContentsOfFile = ObjectiveC.sel_getUid("initWithContentsOfFile:");
|
||||
private static final Pointer initWithData = ObjectiveC.sel_getUid("initWithData:");
|
||||
|
||||
public
|
||||
NSImage(NSData data) {
|
||||
super(ObjectiveC.class_createInstance(objectClass, 0));
|
||||
ObjectiveC.objc_msgSend(this, initWithData, data);
|
||||
}
|
||||
|
||||
public
|
||||
NSImage(BufferedImage image) throws IOException {
|
||||
this(toBytes(image));
|
||||
}
|
||||
|
||||
public
|
||||
NSImage(byte[] imageBytes) {
|
||||
this(new NSData(imageBytes));
|
||||
}
|
||||
|
||||
public
|
||||
NSImage(final File file) {
|
||||
super(ObjectiveC.class_createInstance(objectClass, 0));
|
||||
ObjectiveC.objc_msgSend(this, initWithContentsOfFile, new NSString(file.getAbsolutePath()));
|
||||
}
|
||||
|
||||
private static
|
||||
byte[] toBytes(final BufferedImage image) throws IOException {
|
||||
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
|
||||
ImageIO.write(image, "PNG", byteArrayOutputStream);
|
||||
return byteArrayOutputStream.toByteArray();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* Copyright 2018 dorkbox, llc
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package dorkbox.jna.macos.cocoa;
|
||||
|
||||
import com.sun.jna.NativeLong;
|
||||
|
||||
/**
|
||||
* https://developer.apple.com/documentation/foundation/nsnumber?language=objc
|
||||
*/
|
||||
public
|
||||
class NSInteger extends NativeLong {
|
||||
|
||||
public
|
||||
NSInteger() {
|
||||
}
|
||||
|
||||
public
|
||||
NSInteger(long value) {
|
||||
super(value);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,114 @@
|
|||
/*
|
||||
* Copyright 2018 dorkbox, llc
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package dorkbox.jna.macos.cocoa;
|
||||
|
||||
import com.sun.jna.Pointer;
|
||||
|
||||
import dorkbox.jna.macos.foundation.ObjectiveC;
|
||||
|
||||
/**
|
||||
* https://developer.apple.com/documentation/appkit/nsmenu?language=objc
|
||||
*/
|
||||
public
|
||||
class NSMenu extends NSObject {
|
||||
|
||||
private static final Pointer objectClass = ObjectiveC.objc_lookUpClass("NSMenu");
|
||||
|
||||
private static final Pointer addItem = ObjectiveC.sel_getUid("addItem:");
|
||||
private static final Pointer removeItem = ObjectiveC.sel_getUid("removeItem:");
|
||||
private static final Pointer setAutoenablesItems = ObjectiveC.sel_getUid("setAutoenablesItems:");
|
||||
private static final Pointer itemAtIndex = ObjectiveC.sel_getUid("itemAtIndex:");
|
||||
private static final Pointer insertItemAtIndex = ObjectiveC.sel_getUid("insertItem:atIndex:");
|
||||
|
||||
public
|
||||
NSMenu() {
|
||||
super(ObjectiveC.class_createInstance(objectClass, 0));
|
||||
|
||||
// make this part of the constructor. By default, we want to have items automatically enabled
|
||||
setAutoEnablesItems(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a menu item to the end of the menu.
|
||||
* <p>
|
||||
* NOTE: This method invokes insertItem(_:at:). Thus, the menu does not accept the
|
||||
* menu item if it already belongs to another menu. After adding the menu item, the menu updates itself.
|
||||
*
|
||||
* @param newItem The menu item (an object conforming to the NSMenuItem protocol) to add to the menu.
|
||||
*/
|
||||
public
|
||||
void addItem(NSMenuItem newItem) {
|
||||
ObjectiveC.objc_msgSend(this, addItem, newItem);
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts a menu item into the menu at a specific location.
|
||||
* <p>
|
||||
* NOTE: This method posts an NSMenuDidAddItemNotification, allowing
|
||||
* interested observers to update as appropriate. This method is a primitive
|
||||
* method. All item-addition methods end up calling this method, so this is
|
||||
* where you should implement custom behavior on adding new items to a menu
|
||||
* in a custom subclass. If the menu item already exists in another menu, it
|
||||
* is not inserted and the method raises an exception of type
|
||||
* NSInternalInconsistencyException.
|
||||
*
|
||||
* @param newItem An object conforming to the NSMenuItem protocol that represents a menu item.
|
||||
* @param index An integer index identifying the location of the menu item in the menu.
|
||||
*/
|
||||
public
|
||||
void insertItemAtIndex(NSMenuItem newItem, int index) {
|
||||
ObjectiveC.objc_msgSend(this, insertItemAtIndex, newItem, index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the menu item at a specific location of the menu.
|
||||
*
|
||||
* @param index An integer index locating a menu item in a menu.
|
||||
*
|
||||
* @return The found menu item (an object conforming to the NSMenuItem protocol) or nil if the object couldn't be found.
|
||||
*/
|
||||
public
|
||||
NSMenuItem itemAtIndex(int index) {
|
||||
return new NSMenuItem(ObjectiveC.objc_msgSend(this, itemAtIndex, index));
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates whether the menu automatically enables and disables its menu items.
|
||||
* <p>
|
||||
* This property contains a Boolean value, indicating whether the menu automatically
|
||||
* enables and disables its menu items. If set to true, menu items of the menu are automatically
|
||||
* enabled and disabled according to rules computed by the NSMenuValidation informal protocol.
|
||||
* By default, NSMenu objects autoenable their menu items.
|
||||
*
|
||||
* @param enable true to enable the items by default, false to disable items by default
|
||||
*/
|
||||
public
|
||||
void setAutoEnablesItems(boolean enable) {
|
||||
// WEIRDLY enough, the logic is backwards...
|
||||
ObjectiveC.objc_msgSend(this, setAutoenablesItems, !enable);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Removes a menu item from the menu.
|
||||
*
|
||||
* @param anItem The menu item to remove.
|
||||
*/
|
||||
public
|
||||
void removeItem(final NSMenuItem anItem) {
|
||||
ObjectiveC.objc_msgSend(this, removeItem, anItem);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,163 @@
|
|||
/*
|
||||
* Copyright 2018 dorkbox, llc
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package dorkbox.jna.macos.cocoa;
|
||||
|
||||
import com.sun.jna.Pointer;
|
||||
|
||||
import dorkbox.jna.macos.foundation.ObjectiveC;
|
||||
|
||||
/**
|
||||
* https://developer.apple.com/documentation/appkit/nsmenuitem?language=objc
|
||||
*/
|
||||
public
|
||||
class NSMenuItem extends NSObject {
|
||||
|
||||
private static final Pointer objectClass = ObjectiveC.objc_lookUpClass("NSMenuItem");
|
||||
|
||||
private static final Pointer setTitle = ObjectiveC.sel_getUid("setTitle:");
|
||||
private static final Pointer toolTip = ObjectiveC.sel_getUid("toolTip");
|
||||
private static final Pointer setKeyEquivalent = ObjectiveC.sel_getUid("setKeyEquivalent:");
|
||||
|
||||
private static final Pointer setIndentationLevel = ObjectiveC.sel_getUid("setIndentationLevel:");
|
||||
|
||||
private static final Pointer setImage = ObjectiveC.sel_getUid("setImage:");
|
||||
private static final Pointer setOnStateImage = ObjectiveC.sel_getUid("setOnStateImage:");
|
||||
private static final Pointer setEnabled = ObjectiveC.sel_getUid("setEnabled:");
|
||||
private static final Pointer separatorItem = ObjectiveC.sel_getUid("separatorItem");
|
||||
|
||||
private static final Pointer setSubmenu = ObjectiveC.sel_getUid("setSubmenu:");
|
||||
|
||||
private static final Pointer setState = ObjectiveC.sel_getUid("setState:");
|
||||
private static final Pointer setTarget = ObjectiveC.sel_getUid("setTarget:");
|
||||
private static final Pointer setAction = ObjectiveC.sel_getUid("setAction:");
|
||||
|
||||
public
|
||||
NSMenuItem() {
|
||||
super(ObjectiveC.class_createInstance(objectClass, 0));
|
||||
}
|
||||
|
||||
public
|
||||
NSMenuItem(long peer) {
|
||||
super(peer);
|
||||
}
|
||||
|
||||
/**
|
||||
* A menu item that is used to separate logical groups of menu commands.
|
||||
* <p>
|
||||
* NOTE: This menu item is disabled. The default separator item is blank space.
|
||||
*/
|
||||
public static
|
||||
NSMenuItem separatorItem() {
|
||||
return new NSMenuItem(ObjectiveC.objc_msgSend(objectClass, separatorItem));
|
||||
}
|
||||
|
||||
/**
|
||||
* The menu item's title.
|
||||
*/
|
||||
public
|
||||
void setTitle(NSString title) {
|
||||
ObjectiveC.objc_msgSend(this, setTitle, title);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the menu item's title.
|
||||
*/
|
||||
public
|
||||
NSString setToolTip(NSString tooltip) {
|
||||
return new NSString(ObjectiveC.objc_msgSend(this, toolTip, tooltip));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the menu item indentation level for the menu item.
|
||||
*
|
||||
* @param indentationLevel Value is from 0 to 15. The default indentation level is 0.
|
||||
*/
|
||||
public
|
||||
void setIndentationLevel(NSInteger indentationLevel) {
|
||||
ObjectiveC.objc_msgSend(this, NSMenuItem.setIndentationLevel, indentationLevel);
|
||||
}
|
||||
|
||||
/**
|
||||
* The menu item's shortcut key, if it's a capital letter, then it's a capital letter required for the shortcut
|
||||
* <p>
|
||||
* https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/Button/Tasks/SettingButtonKeyEquiv.html
|
||||
*/
|
||||
public
|
||||
void setKeyEquivalent(NSString characters) {
|
||||
ObjectiveC.objc_msgSend(this, setKeyEquivalent, characters);
|
||||
}
|
||||
|
||||
/**
|
||||
* The menu item’s image.
|
||||
*/
|
||||
public
|
||||
void setImage(NSImage image) {
|
||||
ObjectiveC.objc_msgSend(this, setImage, image);
|
||||
}
|
||||
|
||||
/**
|
||||
* The menu item’s image.
|
||||
*/
|
||||
public
|
||||
void setOnStateImage(NSImage image) {
|
||||
ObjectiveC.objc_msgSend(this, setOnStateImage, image);
|
||||
}
|
||||
|
||||
/**
|
||||
* A Boolean value that indicates whether the menu item is enabled.
|
||||
*/
|
||||
public
|
||||
void setEnabled(boolean enabled) {
|
||||
ObjectiveC.objc_msgSend(this, setEnabled, enabled);
|
||||
}
|
||||
|
||||
/**
|
||||
* The submenu of the menu item.
|
||||
*/
|
||||
public
|
||||
void setSubmenu(NSMenu submenu) {
|
||||
ObjectiveC.objc_msgSend(this, setSubmenu, submenu);
|
||||
}
|
||||
|
||||
/**
|
||||
* The state of the menu item.
|
||||
* <p>
|
||||
* NOTE: The image associated with the new state is displayed to the left of the menu item.
|
||||
*/
|
||||
public
|
||||
void setState(int state) {
|
||||
ObjectiveC.objc_msgSend(this, setState, state);
|
||||
}
|
||||
|
||||
/**
|
||||
* The menu item's target.
|
||||
* <p>
|
||||
* NOTE: To ensure that a menu item’s target can receive commands while a
|
||||
* modal dialog is open, the target object should return YES in worksWhenModal.
|
||||
*/
|
||||
public
|
||||
void setTarget(NSObject target) {
|
||||
ObjectiveC.objc_msgSend(this, setTarget, target);
|
||||
}
|
||||
|
||||
/**
|
||||
* The menu item's action-method selector.
|
||||
*/
|
||||
public
|
||||
void setAction(Pointer pointer) {
|
||||
ObjectiveC.objc_msgSend(this, setAction, pointer);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
* Copyright 2018 dorkbox, llc
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package dorkbox.jna.macos.cocoa;
|
||||
|
||||
import com.sun.jna.Pointer;
|
||||
|
||||
import dorkbox.jna.macos.foundation.ObjectiveC;
|
||||
|
||||
/**
|
||||
* https://developer.apple.com/documentation/objectivec/nsobject?language=objc
|
||||
*/
|
||||
public
|
||||
class NSObject extends Pointer {
|
||||
public static final Pointer objectClass = ObjectiveC.objc_lookUpClass("NSObject");
|
||||
|
||||
private static final Pointer alloc = ObjectiveC.sel_getUid("alloc");
|
||||
private static final Pointer retain = ObjectiveC.sel_getUid("retain");
|
||||
private static final Pointer release = ObjectiveC.sel_getUid("release");
|
||||
|
||||
public
|
||||
NSObject(long peer) {
|
||||
super(peer);
|
||||
|
||||
retain();
|
||||
}
|
||||
|
||||
public
|
||||
NSObject(Pointer pointer) {
|
||||
this(Pointer.nativeValue(pointer));
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
protected
|
||||
void finalize() throws Throwable {
|
||||
release();
|
||||
|
||||
super.finalize();
|
||||
}
|
||||
|
||||
public
|
||||
void alloc() {
|
||||
ObjectiveC.objc_msgSend(this, alloc);
|
||||
}
|
||||
|
||||
|
||||
public
|
||||
void retain() {
|
||||
ObjectiveC.objc_msgSend(this, retain);
|
||||
}
|
||||
|
||||
public
|
||||
void release() {
|
||||
ObjectiveC.objc_msgSend(this, release);
|
||||
}
|
||||
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
public
|
||||
long asPointer() {
|
||||
return Pointer.nativeValue(this);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* Copyright 2018 dorkbox, llc
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package dorkbox.jna.macos.cocoa;
|
||||
|
||||
import com.sun.jna.Pointer;
|
||||
|
||||
import dorkbox.jna.macos.foundation.ObjectiveC;
|
||||
|
||||
/**
|
||||
* https://developer.apple.com/documentation/appkit/nsstatusbar?language=objc
|
||||
*/
|
||||
public
|
||||
class NSStatusBar extends NSObject {
|
||||
|
||||
public final static float NSVariableStatusItemLength = -1; // A status item length that dynamically adjusts to the width of its contents.
|
||||
public final static float NSSquareStatusItemLength = -2; // A status item length that is equal to the status bar’s thickness.
|
||||
|
||||
static Pointer objectClass = ObjectiveC.objc_lookUpClass("NSStatusBar");
|
||||
|
||||
static Pointer systemStatusBar = ObjectiveC.sel_getUid("systemStatusBar");
|
||||
static Pointer statusItemWithLength = ObjectiveC.sel_getUid("statusItemWithLength:");
|
||||
static Pointer removeStatusItem = ObjectiveC.sel_getUid("removeStatusItem:");
|
||||
|
||||
public
|
||||
NSStatusBar(long peer) {
|
||||
super(peer);
|
||||
}
|
||||
|
||||
public static
|
||||
NSStatusBar systemStatusBar() {
|
||||
return new NSStatusBar(ObjectiveC.objc_msgSend(objectClass, systemStatusBar));
|
||||
}
|
||||
|
||||
public
|
||||
NSStatusItem newStatusItem() {
|
||||
long result = ObjectiveC.objc_msgSend(this, statusItemWithLength, NSStatusBar.NSSquareStatusItemLength);
|
||||
return result != 0 ? new NSStatusItem(result) : null;
|
||||
}
|
||||
|
||||
public
|
||||
void removeStatusItem(NSStatusItem statusItem) {
|
||||
ObjectiveC.objc_msgSend(this, removeStatusItem, statusItem);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* Copyright 2018 dorkbox, llc
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package dorkbox.jna.macos.cocoa;
|
||||
|
||||
import com.sun.jna.Pointer;
|
||||
|
||||
import dorkbox.jna.macos.foundation.ObjectiveC;
|
||||
|
||||
/**
|
||||
* https://developer.apple.com/documentation/appkit/nsstatusitem?language=objc
|
||||
*/
|
||||
public
|
||||
class NSStatusItem extends NSObject {
|
||||
|
||||
private static final Pointer setHighlightMode = ObjectiveC.sel_getUid("setHighlightMode:");
|
||||
private static final Pointer setToolTip = ObjectiveC.sel_getUid("setToolTip:");
|
||||
private static final Pointer setMenu = ObjectiveC.sel_getUid("setMenu:");
|
||||
private static final Pointer setImage = ObjectiveC.sel_getUid("setImage:");
|
||||
|
||||
public
|
||||
NSStatusItem(long peer) {
|
||||
super(peer);
|
||||
}
|
||||
|
||||
public
|
||||
void setHighlightMode(boolean highlight) {
|
||||
ObjectiveC.objc_msgSend(this, setHighlightMode, highlight);
|
||||
}
|
||||
|
||||
public
|
||||
void setImage(NSImage image) {
|
||||
ObjectiveC.objc_msgSend(this, setImage, image);
|
||||
}
|
||||
|
||||
public
|
||||
void setMenu(NSMenu menu) {
|
||||
ObjectiveC.objc_msgSend(this, setMenu, menu);
|
||||
}
|
||||
|
||||
public
|
||||
void setToolTip(NSString tooltip) {
|
||||
ObjectiveC.objc_msgSend(this, setToolTip, tooltip);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* Copyright 2018 dorkbox, llc
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package dorkbox.jna.macos.cocoa;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
|
||||
import com.sun.jna.Pointer;
|
||||
|
||||
import dorkbox.jna.macos.foundation.ObjectiveC;
|
||||
|
||||
/**
|
||||
* https://developer.apple.com/documentation/foundation/nsstring?language=objc
|
||||
*/
|
||||
public
|
||||
class NSString extends NSObject {
|
||||
private static final Charset UTF8 = Charset.forName("UTF-8");
|
||||
|
||||
static
|
||||
Object asBytes(String string) {
|
||||
return (string + "\0").getBytes(UTF8);
|
||||
}
|
||||
|
||||
|
||||
private static final Pointer objectClass = ObjectiveC.objc_lookUpClass("NSString");
|
||||
|
||||
private static final Pointer stringWithUTF8String = ObjectiveC.sel_getUid("stringWithUTF8String:");
|
||||
private static final Pointer UTF8String = ObjectiveC.sel_getUid("UTF8String");
|
||||
|
||||
public
|
||||
NSString(long peer) {
|
||||
super(peer);
|
||||
}
|
||||
|
||||
public
|
||||
NSString(String string) {
|
||||
this(ObjectiveC.objc_msgSend(objectClass, stringWithUTF8String, asBytes(string)));
|
||||
}
|
||||
|
||||
public
|
||||
String toString() {
|
||||
long pointerReference = ObjectiveC.objc_msgSend(this, UTF8String);
|
||||
return new Pointer(pointerReference).getString(0);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
* Copyright 2018 dorkbox, llc
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package dorkbox.jna.macos.cocoa;
|
||||
|
||||
public
|
||||
interface OsxClickCallback {
|
||||
void click();
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
/*
|
||||
* Copyright 2021 dorkbox, llc
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package dorkbox.jna.macos.cocoa;
|
|
@ -0,0 +1,157 @@
|
|||
/*
|
||||
* Copyright 2018 dorkbox, llc
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package dorkbox.jna.macos.foundation;
|
||||
|
||||
import com.sun.jna.Callback;
|
||||
import com.sun.jna.Library;
|
||||
import com.sun.jna.Native;
|
||||
import com.sun.jna.Pointer;
|
||||
|
||||
/**
|
||||
* "how to" from: https://gist.github.com/3974488
|
||||
* <p>
|
||||
* https://developer.apple.com/documentation/objectivec/objective-c_runtime
|
||||
* <p>
|
||||
* We cannot use JNA "direct mapping", because direct mapping DOES NOT support var-args (which `objc_msgSend` requires)
|
||||
*/
|
||||
public
|
||||
class ObjectiveC {
|
||||
interface Objc extends Library {
|
||||
Pointer objc_lookUpClass(String name);
|
||||
|
||||
long objc_msgSend(Pointer theReceiver, Pointer theSelector, Object... string);
|
||||
|
||||
Pointer objc_allocateClassPair(Pointer superClass, String name, long extraBytes);
|
||||
|
||||
void objc_registerClassPair(Pointer clazz);
|
||||
|
||||
Pointer class_createInstance(Pointer clazz, int extraBytes);
|
||||
|
||||
boolean class_addMethod(Pointer clazz, Pointer selector, Callback callback, String types);
|
||||
|
||||
Pointer sel_getUid(String name);
|
||||
|
||||
Pointer sel_registerName(String name);
|
||||
}
|
||||
|
||||
private static final Objc INSTANCE = Native.load("objc", Objc.class);
|
||||
|
||||
/**
|
||||
* Returns the class definition of a specified class.
|
||||
*
|
||||
* @param name The name of the class to look up.
|
||||
*
|
||||
* @return The Class object for the named class, or nil if the class is not registered with the Objective-C runtime.
|
||||
*/
|
||||
public static
|
||||
Pointer objc_lookUpClass(String name) {
|
||||
return INSTANCE.objc_lookUpClass(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a message with a simple return value to an instance of a class.
|
||||
*
|
||||
* @param self A pointer that points to the instance of the class that is to receive the message.
|
||||
* @param op The selector of the method that handles the message.
|
||||
* @param args A variable argument list containing the arguments to the method.
|
||||
*
|
||||
* @return The return value of the method.
|
||||
*/
|
||||
public static
|
||||
long objc_msgSend(Pointer self, Pointer op, Object... args) {
|
||||
return INSTANCE.objc_msgSend(self, op, args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new class and metaclass.
|
||||
*
|
||||
* @param superClass The class to use as the new class's superclass, or Nil to create a new root class.
|
||||
* @param name The string to use as the new class's name. The string will be copied.
|
||||
* @param extraBytes The number of bytes to allocate for indexed ivars at the end of the class and metaclass objects. This should usually be 0.
|
||||
*
|
||||
* @return The new class, or Nil if the class could not be created (for example, the desired name is already in use).
|
||||
*/
|
||||
public static
|
||||
Pointer objc_allocateClassPair(Pointer superClass, String name, long extraBytes) {
|
||||
return INSTANCE.objc_allocateClassPair(superClass, name, extraBytes);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Registers a class that was allocated using objc_allocateClassPair.
|
||||
*
|
||||
* @param cls The class you want to register.
|
||||
*/
|
||||
public static
|
||||
void objc_registerClassPair(Pointer cls) {
|
||||
INSTANCE.objc_registerClassPair(cls);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance of a class, allocating memory for the class in the default malloc memory zone.
|
||||
*
|
||||
* @param cls The class that you want to allocate an instance of.
|
||||
* @param extraBytes An integer indicating the number of extra bytes to allocate. The additional bytes can be used to store additional instance variables beyond those defined in the class definition.
|
||||
*
|
||||
* @return An instance of the class cls.
|
||||
*/
|
||||
public static
|
||||
Pointer class_createInstance(Pointer cls, int extraBytes) {
|
||||
return INSTANCE.class_createInstance(cls, extraBytes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new method to a class with a given name and implementation.
|
||||
* NOTE: class_addMethod will add an override of a superclass's implementation, but will not replace an existing implementation in this class. To change an existing implementation, use method_setImplementation.
|
||||
*
|
||||
* @param cls The class to which to add a method.
|
||||
* @param name A selector that specifies the name of the method being added.
|
||||
* @param imp A function which is the implementation of the new method. The function must take at least two arguments—self and _cmd.
|
||||
* @param types An array of characters that describe the types of the arguments to the method. For possible values, see Objective-C Runtime Programming Guide > Type Encodings. Since the function must take at least two arguments—self and _cmd, the second and third characters must be "@:" (the first character is the return type).
|
||||
*
|
||||
* @return YES if the method was added successfully, otherwise NO (for example, the class already contains a method implementation with that name).
|
||||
*/
|
||||
public static
|
||||
boolean class_addMethod(Pointer cls, Pointer name, Callback imp, String types) {
|
||||
return INSTANCE.class_addMethod(cls, name, imp, types);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a method name with the Objective-C runtime system.
|
||||
* NOTE: The implementation of this method is identical to the implementation of sel_registerName.
|
||||
*
|
||||
* @param str A pointer to a C string. Pass the name of the method you wish to register.
|
||||
*
|
||||
* @return A pointer of type SEL specifying the selector for the named method.
|
||||
*/
|
||||
public static
|
||||
Pointer sel_getUid(String str) {
|
||||
return INSTANCE.sel_getUid(str);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a method with the Objective-C runtime system, maps the method name to a selector, and returns the selector value.
|
||||
* NOTE: You must register a method name with the Objective-C runtime system to obtain the method’s selector before you can add the method to a class definition. If the method name has already been registered, this function simply returns the selector.
|
||||
*
|
||||
* @param str A pointer to a C string. Pass the name of the method you wish to register.
|
||||
*
|
||||
* @return A pointer of type SEL specifying the selector for the named method.
|
||||
*/
|
||||
public static
|
||||
Pointer sel_registerName(String str) {
|
||||
return INSTANCE.sel_registerName(str);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
/*
|
||||
* Copyright 2021 dorkbox, llc
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package dorkbox.jna.macos.foundation;
|
|
@ -0,0 +1,17 @@
|
|||
/*
|
||||
* Copyright 2021 dorkbox, llc
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package dorkbox.jna.macos;
|
|
@ -0,0 +1,17 @@
|
|||
/*
|
||||
* Copyright 2021 dorkbox, llc
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package dorkbox.jna;
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* Copyright 2021 dorkbox, llc
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package dorkbox.jna.rendering;
|
||||
|
||||
class DefaultProvider implements Renderer {
|
||||
@Override
|
||||
public
|
||||
boolean isSupported() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public
|
||||
ProviderType getType() {
|
||||
return ProviderType.NONE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public
|
||||
boolean alreadyRunning() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public
|
||||
boolean isEventThread() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public
|
||||
int getGtkVersion() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public
|
||||
boolean dispatch(final Runnable runnable) {
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
* Copyright 2021 dorkbox, llc
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package dorkbox.jna.rendering;
|
||||
|
||||
public
|
||||
enum ProviderType {
|
||||
SWT, JAVAFX, NONE
|
||||
}
|
|
@ -0,0 +1,120 @@
|
|||
/*
|
||||
* Copyright 2021 dorkbox, llc
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package dorkbox.jna.rendering;
|
||||
|
||||
/**
|
||||
* A "RenderProvider", is either None (internal implementation), JavaFX (either from Oracle, or the OpenJavaFX), or SWT (from Eclipse).
|
||||
*/
|
||||
public
|
||||
class RenderProvider {
|
||||
private static Renderer provider = new DefaultProvider();
|
||||
|
||||
/**
|
||||
* Assigns the specified provider. This is primarily used by the SystemTray and GTK applications.
|
||||
*
|
||||
* @param provider which provider is used. This will change from the default provider to SWT or JAVAFX
|
||||
*/
|
||||
public static void set(Renderer provider) {
|
||||
RenderProvider.provider = provider;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if the render provider is supported (correct library versions, etc)
|
||||
*/
|
||||
public static
|
||||
boolean isSupported() {
|
||||
return provider.isSupported();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if the GTK provider type is the default provider.
|
||||
*/
|
||||
public static
|
||||
boolean isDefault() {
|
||||
return provider.getType() == ProviderType.NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if the GTK provider type is JavaFX.
|
||||
*/
|
||||
public static
|
||||
boolean isJavaFX() {
|
||||
return provider.getType() == ProviderType.JAVAFX;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if the GTK provider type is SWT
|
||||
*/
|
||||
public static
|
||||
boolean isSwt() {
|
||||
return provider.getType() == ProviderType.SWT;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the GTK provider type. SWT or JAVAFX (or none, if it's the null provider)
|
||||
*/
|
||||
public static
|
||||
ProviderType getType() {
|
||||
return provider.getType();
|
||||
}
|
||||
|
||||
/**
|
||||
* Necessary to determine if the current execution thread is the event dispatch thread, or a different thread
|
||||
*
|
||||
* @return true if the current thread is the dispatch/event thread
|
||||
*/
|
||||
public static
|
||||
boolean isEventThread() {
|
||||
return provider.isEventThread();
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to discover the in-use version of GTK by the system (where appropriate) during startup.
|
||||
*
|
||||
* If this provider is not 'loaded', then this method will not be called.
|
||||
*
|
||||
* @return the GTK version in use by the provider. A return 0 will skip this provider's GTK version info
|
||||
*/
|
||||
public static
|
||||
int getGtkVersion() {
|
||||
return provider.getGtkVersion();
|
||||
}
|
||||
|
||||
/**
|
||||
* If we are currently on the dispatch thread, then we want to execute this task immediately. Otherwise, this task should be executed
|
||||
* on the dispatch thread
|
||||
*
|
||||
* @return true if this task was dispatched by this provider, false if the default provider should handle it
|
||||
*/
|
||||
public static
|
||||
boolean dispatch(final Runnable runnable) {
|
||||
return provider.dispatch(runnable);
|
||||
}
|
||||
|
||||
/**
|
||||
* depending on how the system is initialized, SWT may, or may not, have the gtk_main loop running. It will EVENTUALLY run, so we
|
||||
* do not want to run our own GTK event loop.
|
||||
*
|
||||
* JavaFX is not so strange in how GTK starts, so (at least for now), we only care about SWT being loaded
|
||||
*
|
||||
* @return if we are SWT, then we are considered "already running". JavaFx provides a method to detected if it's running at startup
|
||||
*/
|
||||
public static
|
||||
boolean alreadyRunning() {
|
||||
return provider.alreadyRunning();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* Copyright 2021 dorkbox, llc
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package dorkbox.jna.rendering;
|
||||
|
||||
public
|
||||
interface Renderer {
|
||||
boolean isSupported();
|
||||
|
||||
/**
|
||||
* @return the GTK provider type. SWT or JAVAFX
|
||||
*/
|
||||
ProviderType getType();
|
||||
|
||||
/**
|
||||
* depending on how the system is initialized, SWT may, or may not, have the gtk_main loop running. It will EVENTUALLY run, so we
|
||||
* do not want to run our own GTK event loop.
|
||||
* <p>
|
||||
* JavaFX is not so strange in how GTK starts, so (at least for now), we only care about SWT being loaded
|
||||
*
|
||||
* @return if we are SWT, then we are considered "already running"
|
||||
*/
|
||||
boolean alreadyRunning();
|
||||
|
||||
/**
|
||||
* Necessary to determine if the current execution thread is the event dispatch thread, or a different thread
|
||||
*
|
||||
* @return true if the current thread is the dispatch/event thread
|
||||
*/
|
||||
boolean isEventThread();
|
||||
|
||||
/**
|
||||
* Used to discover the in-use version of GTK by the system (where appropriate) during startup.
|
||||
* <p>
|
||||
* If this provider is not 'loaded', then this method will not be called.
|
||||
*
|
||||
* @return the GTK version in use by the provider. A value of 0 means "ignore this"
|
||||
*/
|
||||
int getGtkVersion();
|
||||
|
||||
boolean dispatch(final Runnable runnable);
|
||||
}
|
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
* Copyright 2017 dorkbox, llc
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package dorkbox.jna.windows;
|
||||
|
||||
import static com.sun.jna.platform.win32.WinDef.HBITMAP;
|
||||
import static com.sun.jna.platform.win32.WinDef.HDC;
|
||||
import static com.sun.jna.platform.win32.WinGDI.BITMAPINFO;
|
||||
import static com.sun.jna.platform.win32.WinNT.HANDLE;
|
||||
|
||||
import com.sun.jna.Pointer;
|
||||
import com.sun.jna.ptr.PointerByReference;
|
||||
|
||||
import dorkbox.jna.JNA;
|
||||
|
||||
public
|
||||
class GDI32 {
|
||||
static {
|
||||
JNA.register("GDI32", GDI32.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* The CreateCompatibleDC function creates a memory device context (DC) compatible with the specified device.
|
||||
*
|
||||
* @param hDC Handle to an existing DC. If this handle is NULL, the function creates a memory DC compatible with the
|
||||
* application's current screen.
|
||||
*
|
||||
* @return If the function succeeds, the return value is the handle to a memory DC.
|
||||
* If the function fails, the return value is NULL.
|
||||
* To get extended error information, call GetLastError.
|
||||
*/
|
||||
public static native
|
||||
HDC CreateCompatibleDC(HDC hDC);
|
||||
|
||||
/**
|
||||
* The DeleteDC function deletes the specified device context (DC).
|
||||
*
|
||||
* @param hDC Handle to the device context.
|
||||
*
|
||||
* @return If the function succeeds, the return value is nonzero.
|
||||
* If the function fails, the return value is zero.
|
||||
* To get extended error information, call GetLastError.
|
||||
*/
|
||||
public static native
|
||||
boolean DeleteDC(HDC hDC);
|
||||
|
||||
/**
|
||||
* The DeleteObject function deletes a logical pen, brush, font, bitmap, region, or palette,
|
||||
* freeing all system resources associated with the object. After the object is deleted, the
|
||||
* specified handle is no longer valid.
|
||||
*
|
||||
* @param hObject Handle to a logical pen, brush, font, bitmap, region, or palette.
|
||||
*
|
||||
* @return If the function succeeds, the return value is nonzero.
|
||||
* If the specified handle is not valid or is currently selected into a DC, the return value is zero.
|
||||
* To get extended error information, call GetLastError.
|
||||
*/
|
||||
public static native
|
||||
boolean DeleteObject(HANDLE hObject);
|
||||
|
||||
/**
|
||||
* The CreateDIBSection function creates a DIB that applications can write to directly.
|
||||
* The function gives you a pointer to the location of the bitmap bit values. You can supply
|
||||
* a handle to a file-mapping object that the function will use to create the bitmap, or you
|
||||
* can let the system allocate the memory for the bitmap.
|
||||
*
|
||||
* @param hDC Handle to a device context. If the value of iUsage is DIB_PAL_COLORS, the function uses this
|
||||
* device context's logical palette to initialize the DIB colors.
|
||||
* @param pbmi Pointer to a BITMAPINFO structure that specifies various attributes of the DIB, including
|
||||
* the bitmap dimensions and colors.
|
||||
* @param iUsage Specifies the type of data contained in the bmiColors array member of the BITMAPINFO structure
|
||||
* pointed to by pbmi (either logical palette indexes or literal RGB values).
|
||||
* @param ppvBits Pointer to a variable that receives a pointer to the location of the DIB bit values.
|
||||
* @param hSection Handle to a file-mapping object that the function will use to create the DIB. This parameter can be NULL.
|
||||
* @param dwOffset Specifies the offset from the beginning of the file-mapping object referenced by hSection where storage
|
||||
* for the bitmap bit values is to begin.
|
||||
*
|
||||
* @return Specifies the offset from the beginning of the file-mapping object referenced by hSection where storage
|
||||
* for the bitmap bit values is to begin.
|
||||
*/
|
||||
public static native
|
||||
HBITMAP CreateDIBSection(HDC hDC, BITMAPINFO pbmi, int iUsage, PointerByReference ppvBits, Pointer hSection, int dwOffset);
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* Copyright 2017 dorkbox, llc
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package dorkbox.jna.windows;
|
||||
|
||||
import com.sun.jna.platform.win32.Kernel32Util;
|
||||
|
||||
public
|
||||
class GetLastErrorException extends RuntimeException {
|
||||
private static final long serialVersionUID = 3980497906900380359L;
|
||||
|
||||
private String message;
|
||||
|
||||
public
|
||||
GetLastErrorException() {
|
||||
message = Kernel32Util.getLastErrorMessage();
|
||||
}
|
||||
|
||||
public
|
||||
String toString() {
|
||||
return message;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,129 @@
|
|||
/*
|
||||
* Copyright 2017 dorkbox, llc
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package dorkbox.jna.windows;
|
||||
|
||||
import static com.sun.jna.platform.win32.WinDef.HBITMAP;
|
||||
import static com.sun.jna.platform.win32.WinDef.HDC;
|
||||
import static dorkbox.jna.windows.User32.User32;
|
||||
|
||||
import java.awt.AlphaComposite;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.Raster;
|
||||
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.sun.jna.Memory;
|
||||
import com.sun.jna.Pointer;
|
||||
import com.sun.jna.platform.win32.Kernel32Util;
|
||||
import com.sun.jna.platform.win32.WinGDI;
|
||||
import com.sun.jna.ptr.PointerByReference;
|
||||
|
||||
public class HBITMAPWrap extends HBITMAP {
|
||||
|
||||
private static final Object lockObject = new Object();
|
||||
|
||||
// NOTE: This is a field (instead of private) so that GC does not try to collect this object
|
||||
private HBITMAP bitmap;
|
||||
|
||||
// https://github.com/twall/jna/blob/master/contrib/alphamaskdemo/com/sun/jna/contrib/demo/AlphaMaskDemo.java
|
||||
private static
|
||||
HBITMAP createBitmap(BufferedImage image) {
|
||||
int w = image.getWidth(null);
|
||||
int h = image.getHeight(null);
|
||||
|
||||
// all sorts of issues occur if this is called quickly from different threads!
|
||||
synchronized(lockObject) {
|
||||
HDC screenDC = User32.GetDC(null);
|
||||
HDC memDC = GDI32.CreateCompatibleDC(screenDC);
|
||||
HBITMAP hBitmap = null;
|
||||
|
||||
try {
|
||||
BufferedImage buf = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB_PRE);
|
||||
Graphics2D g = (Graphics2D) buf.getGraphics();
|
||||
g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER));
|
||||
g.drawImage(image, 0, 0, w, h, null);
|
||||
|
||||
WinGDI.BITMAPINFO bmi = new WinGDI.BITMAPINFO();
|
||||
bmi.bmiHeader.biWidth = w;
|
||||
bmi.bmiHeader.biHeight = h;
|
||||
bmi.bmiHeader.biPlanes = 1;
|
||||
bmi.bmiHeader.biBitCount = 32;
|
||||
bmi.bmiHeader.biCompression = WinGDI.BI_RGB;
|
||||
bmi.bmiHeader.biSizeImage = w * h * 4;
|
||||
|
||||
Memory memory = new Memory(w*h*32*4);
|
||||
PointerByReference pointerRef = new PointerByReference(memory);
|
||||
hBitmap = GDI32.CreateDIBSection(memDC, bmi, WinGDI.DIB_RGB_COLORS, pointerRef, null, 0);
|
||||
Pointer pointerToBits = pointerRef.getValue();
|
||||
|
||||
if (pointerToBits == null) {
|
||||
// the bitmap was invalid
|
||||
LoggerFactory.getLogger(HBITMAPWrap.class).error("The image was invalid", Kernel32Util.getLastErrorMessage());
|
||||
}
|
||||
else {
|
||||
Raster raster = buf.getData();
|
||||
int[] pixel = new int[4];
|
||||
int[] bits = new int[w * h];
|
||||
for (int y = 0; y < h; y++) {
|
||||
for (int x = 0; x < w; x++) {
|
||||
raster.getPixel(x, h - y - 1, pixel);
|
||||
int red = (pixel[2] & 0xFF) << 0;
|
||||
int green = (pixel[1] & 0xFF) << 8;
|
||||
int blue = (pixel[0] & 0xFF) << 16;
|
||||
int alpha = (pixel[3] & 0xFF) << 24;
|
||||
bits[x + y * w] = alpha | red | green | blue;
|
||||
}
|
||||
}
|
||||
pointerToBits.write(0, bits, 0, bits.length);
|
||||
}
|
||||
|
||||
return hBitmap;
|
||||
} finally {
|
||||
User32.ReleaseDC(null, screenDC);
|
||||
GDI32.DeleteDC(memDC);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BufferedImage img;
|
||||
|
||||
public HBITMAPWrap(BufferedImage img) {
|
||||
bitmap = createBitmap(img);
|
||||
setPointer(bitmap.getPointer());
|
||||
|
||||
this.img = img;
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
protected void finalize() throws Throwable {
|
||||
close();
|
||||
super.finalize();
|
||||
}
|
||||
|
||||
public void close() {
|
||||
if (Pointer.nativeValue(getPointer()) != 0) {
|
||||
GDI32.DeleteObject(this);
|
||||
setPointer(new Pointer(0));
|
||||
bitmap = null;
|
||||
}
|
||||
}
|
||||
|
||||
public BufferedImage getImage() {
|
||||
return img;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
* Copyright 2017 dorkbox, llc
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package dorkbox.jna.windows;
|
||||
|
||||
import static com.sun.jna.platform.win32.WinDef.HBITMAP;
|
||||
import static com.sun.jna.platform.win32.WinDef.HICON;
|
||||
import static dorkbox.jna.windows.User32.User32;
|
||||
|
||||
import com.sun.jna.Pointer;
|
||||
|
||||
import dorkbox.jna.windows.structs.ICONINFO;
|
||||
|
||||
/**
|
||||
* http://www.pinvoke.net/default.aspx/user32.createiconindirect
|
||||
*/
|
||||
public class HICONWrap extends HICON {
|
||||
private static final Object lockObject = new Object();
|
||||
|
||||
static HICON createIconIndirect(HBITMAP bm) {
|
||||
ICONINFO info = new ICONINFO();
|
||||
info.IsIcon = true;
|
||||
info.MaskBitmap = bm;
|
||||
info.ColorBitmap = bm;
|
||||
|
||||
HICON hicon = User32.CreateIconIndirect(info);
|
||||
if (hicon == null) {
|
||||
// something weird is going on! Try again but more carefully!
|
||||
synchronized(lockObject) {
|
||||
hicon = User32.CreateIconIndirect(info);
|
||||
}
|
||||
|
||||
if (hicon == null) {
|
||||
throw new GetLastErrorException();
|
||||
}
|
||||
}
|
||||
|
||||
return hicon;
|
||||
}
|
||||
|
||||
private HBITMAPWrap bm;
|
||||
|
||||
public HICONWrap() {
|
||||
}
|
||||
|
||||
public HICONWrap(Pointer p) {
|
||||
super(p);
|
||||
}
|
||||
|
||||
public HICONWrap(HBITMAPWrap bm) {
|
||||
this.bm = bm;
|
||||
setPointer(createIconIndirect(bm).getPointer());
|
||||
}
|
||||
|
||||
public void close() {
|
||||
bm.close();
|
||||
|
||||
if (Pointer.nativeValue(getPointer()) != 0) {
|
||||
GDI32.DeleteObject(this);
|
||||
setPointer(new Pointer(0));
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
protected void finalize() throws Throwable {
|
||||
close();
|
||||
super.finalize();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,137 @@
|
|||
/*
|
||||
* Copyright 2017 dorkbox, llc
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package dorkbox.jna.windows;
|
||||
|
||||
import static com.sun.jna.platform.win32.WinNT.HANDLE;
|
||||
|
||||
import com.sun.jna.platform.win32.Kernel32Util;
|
||||
import com.sun.jna.ptr.IntByReference;
|
||||
|
||||
import dorkbox.jna.JNA;
|
||||
import dorkbox.jna.windows.structs.CONSOLE_SCREEN_BUFFER_INFO;
|
||||
import dorkbox.jna.windows.structs.COORD;
|
||||
import dorkbox.jna.windows.structs.INPUT_RECORD;
|
||||
import dorkbox.jna.windows.structs.SMALL_RECT;
|
||||
|
||||
public
|
||||
class Kernel32 {
|
||||
static {
|
||||
JNA.register("kernel32", Kernel32.class);
|
||||
}
|
||||
|
||||
// see: http://msdn.microsoft.com/en-us/library/ms682013%28VS.85%29.aspx
|
||||
public static final short FOREGROUND_BLACK = (short) 0x0000;
|
||||
public static final short FOREGROUND_BLUE = (short) 0x0001;
|
||||
public static final short FOREGROUND_GREEN = (short) 0x0002;
|
||||
public static final short FOREGROUND_CYAN = (short) 0x0003;
|
||||
public static final short FOREGROUND_RED = (short) 0x0004;
|
||||
public static final short FOREGROUND_MAGENTA = (short) 0x0005;
|
||||
public static final short FOREGROUND_YELLOW = (short) 0x0006;
|
||||
public static final short FOREGROUND_GREY = (short) 0x0007;
|
||||
public static final short FOREGROUND_INTENSITY = (short) 0x0008; // foreground color is intensified.
|
||||
|
||||
public static final short BACKGROUND_BLACK = (short) 0x0000;
|
||||
public static final short BACKGROUND_BLUE = (short) 0x0010;
|
||||
public static final short BACKGROUND_GREEN = (short) 0x0020;
|
||||
public static final short BACKGROUND_CYAN = (short) 0x0030;
|
||||
public static final short BACKGROUND_RED = (short) 0x0040;
|
||||
public static final short BACKGROUND_MAGENTA = (short) 0x0050;
|
||||
public static final short BACKGROUND_YELLOW = (short) 0x0060;
|
||||
public static final short BACKGROUND_GREY = (short) 0x0070;
|
||||
public static final short BACKGROUND_INTENSITY = (short) 0x0080; // background color is intensified.
|
||||
|
||||
|
||||
public static final short COMMON_LVB_LEADING_BYTE = (short) 0x0100;
|
||||
public static final short COMMON_LVB_TRAILING_BYTE = (short) 0x0200;
|
||||
public static final short COMMON_LVB_GRID_HORIZONTAL = (short) 0x0400;
|
||||
public static final short COMMON_LVB_GRID_LVERTICAL = (short) 0x0800;
|
||||
public static final short COMMON_LVB_GRID_RVERTICAL = (short) 0x1000;
|
||||
public static final short COMMON_LVB_REVERSE_VIDEO = (short) 0x4000;
|
||||
public static final short COMMON_LVB_UNDERSCORE = (short) 0x8000;
|
||||
|
||||
public static final int FORMAT_MESSAGE_FROM_SYSTEM = 0x1000;
|
||||
|
||||
public static void ASSERT(final int returnValue, final String message) {
|
||||
// if returnValue == 0, throw assertion error
|
||||
assert returnValue != 0 : message + " : " + Kernel32Util.getLastErrorMessage();
|
||||
}
|
||||
|
||||
/**
|
||||
* https://msdn.microsoft.com/en-us/library/ms683231%28VS.85%29.aspx
|
||||
*/
|
||||
public static native
|
||||
HANDLE GetStdHandle(int stdHandle);
|
||||
|
||||
/**
|
||||
* https://msdn.microsoft.com/en-us/library/ms724211%28VS.85%29.aspx
|
||||
*/
|
||||
public static native
|
||||
int CloseHandle(HANDLE handle);
|
||||
|
||||
/**
|
||||
* https://msdn.microsoft.com/en-us/library/ms686047%28VS.85%29.aspx
|
||||
*/
|
||||
public static native
|
||||
int SetConsoleTextAttribute(HANDLE consoleOutput, short attributes);
|
||||
|
||||
/**
|
||||
* https://msdn.microsoft.com/en-us/library/ms683171%28VS.85%29.aspx
|
||||
*/
|
||||
public static native
|
||||
int GetConsoleScreenBufferInfo(HANDLE consoleOutput, CONSOLE_SCREEN_BUFFER_INFO consoleScreenBufferInfo);
|
||||
|
||||
/**
|
||||
* https://msdn.microsoft.com/en-us/library/windows/desktop/ms686025(v=vs.85).aspx
|
||||
*/
|
||||
public static native
|
||||
int SetConsoleCursorPosition(HANDLE consoleOutput, COORD.ByValue cursorPosition);
|
||||
|
||||
/**
|
||||
* https://msdn.microsoft.com/en-us/library/windows/desktop/ms685107(v=vs.85).aspx
|
||||
*/
|
||||
public static native
|
||||
int ScrollConsoleScreenBuffer(HANDLE consoleOutput, SMALL_RECT.ByReference scrollRect, SMALL_RECT.ByReference clipRect, COORD.ByValue destinationOrigin, IntByReference fillAttributes);
|
||||
|
||||
/**
|
||||
* https://msdn.microsoft.com/en-us/library/ms682662%28VS.85%29.aspx
|
||||
*/
|
||||
public static native
|
||||
int FillConsoleOutputAttribute(HANDLE consoleOutput, short attribute, int length, COORD.ByValue writeCoord, IntByReference numberOfAttrsWritten);
|
||||
|
||||
/**
|
||||
* https://msdn.microsoft.com/en-us/library/ms682663%28VS.85%29.aspx
|
||||
*/
|
||||
public static native
|
||||
int FillConsoleOutputCharacter(HANDLE consoleOutput, char character, int length, COORD.ByValue writeCoord, IntByReference numberOfCharsWritten);
|
||||
|
||||
/**
|
||||
* https://msdn.microsoft.com/en-us/library/ms683167%28VS.85%29.aspx
|
||||
*/
|
||||
public static native
|
||||
int GetConsoleMode(HANDLE handle, IntByReference mode);
|
||||
|
||||
/**
|
||||
* https://msdn.microsoft.com/en-us/library/ms686033%28VS.85%29.aspx
|
||||
*/
|
||||
public static native
|
||||
int SetConsoleMode(HANDLE handle, int mode);
|
||||
|
||||
/**
|
||||
* https://msdn.microsoft.com/en-us/library/ms684961(v=VS.85).aspx
|
||||
*/
|
||||
public static native
|
||||
int ReadConsoleInput(HANDLE handle, INPUT_RECORD.ByReference inputRecords, int length, IntByReference eventsCount);
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* Copyright 2017 dorkbox, llc
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package dorkbox.jna.windows;
|
||||
|
||||
import static com.sun.jna.platform.win32.WinDef.HWND;
|
||||
import static com.sun.jna.platform.win32.WinDef.LPARAM;
|
||||
import static com.sun.jna.platform.win32.WinDef.WPARAM;
|
||||
|
||||
public
|
||||
class Listener {
|
||||
public
|
||||
void run(HWND hWnd, WPARAM wParam, LPARAM lParam) {
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Copyright 2017 dorkbox, llc
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package dorkbox.jna.windows;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import com.sun.jna.Pointer;
|
||||
import com.sun.jna.Structure;
|
||||
|
||||
public
|
||||
class MSG extends Structure {
|
||||
public Pointer hWnd;
|
||||
public int message;
|
||||
public Parameter wParam;
|
||||
public Parameter lParam;
|
||||
public int time;
|
||||
public int x;
|
||||
public int y;
|
||||
|
||||
@Override
|
||||
protected
|
||||
List<String> getFieldOrder() {
|
||||
return Arrays.asList("hWnd", "message", "wParam", "lParam", "time", "x", "y");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package dorkbox.jna.windows;
|
||||
|
||||
import com.sun.jna.IntegerType;
|
||||
import com.sun.jna.Native;
|
||||
|
||||
public
|
||||
class Parameter extends IntegerType {
|
||||
public
|
||||
Parameter() {
|
||||
this(0);
|
||||
}
|
||||
|
||||
public
|
||||
Parameter(long value) {
|
||||
super(Native.POINTER_SIZE, value);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,85 @@
|
|||
/*
|
||||
* Copyright 2021 dorkbox, llc
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package dorkbox.jna.windows;
|
||||
|
||||
import com.sun.jna.Function;
|
||||
import com.sun.jna.NativeLibrary;
|
||||
import com.sun.jna.platform.win32.WinNT;
|
||||
import com.sun.jna.platform.win32.WinUser;
|
||||
import com.sun.jna.ptr.IntByReference;
|
||||
|
||||
import dorkbox.jna.JNA;
|
||||
import dorkbox.os.OS;
|
||||
|
||||
/**
|
||||
* bindings for ShCore.dll
|
||||
*
|
||||
* Minimum supported client
|
||||
* Windows 8.1 [desktop apps only]
|
||||
*
|
||||
* Minimum supported server
|
||||
* Windows Server 2012 R2 [desktop apps only]
|
||||
*
|
||||
* <p>
|
||||
* Direct-mapping, See: https://github.com/java-native-access/jna/blob/master/www/DirectMapping.md
|
||||
*/
|
||||
public
|
||||
class ShCore {
|
||||
private static Function GetDpiForMonitor = null;
|
||||
|
||||
static {
|
||||
if (OS.Windows.INSTANCE.isWindows8_1_plus()) {
|
||||
NativeLibrary library = JNA.register("shcore", ShCore.class);
|
||||
|
||||
// Abusing static fields this way is not proper, but it gets the job done nicely.
|
||||
// GetDpiForMonitor is NOT always available! (Windows 8.1+)
|
||||
GetDpiForMonitor = library.getFunction("GetDpiForMonitor");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* https://msdn.microsoft.com/de-de/library/windows/desktop/dn280510(v=vs.85).aspx
|
||||
*
|
||||
* @param hMonitor A handle to the window whose DC is to be retrieved. If this value is NULL, GetDC retrieves the DC for the entire
|
||||
* screen.
|
||||
*
|
||||
* @param dpiType
|
||||
* MDT_EFFECTIVE_DPI = 0,
|
||||
* The effective DPI. This value should be used when determining the correct scale factor for scaling UI elements. This
|
||||
* incorporates the scale factor set by the user for this specific display.
|
||||
* MDT_ANGULAR_DPI = 1,
|
||||
* The angular DPI. This DPI ensures rendering at a compliant angular resolution on the screen. This does not include the
|
||||
* scale factor set by the user for this specific display.
|
||||
* MDT_RAW_DPI = 2,
|
||||
* The raw DPI. This value is the linear DPI of the screen as measured on the screen itself. Use this value when you want
|
||||
* to read the pixel density and not the recommended scaling setting. This does not include the scale factor set by the user
|
||||
* for this specific display and is not guaranteed to be a supported DPI value.
|
||||
* MDT_DEFAULT = MDT_EFFECTIVE_DPI
|
||||
*
|
||||
*
|
||||
* @return if the function succeeds, the return value is a handle to the DC for the specified window's client area. If the function
|
||||
* fails, the return value is NULL.
|
||||
*/
|
||||
public static
|
||||
WinNT.HRESULT GetDpiForMonitor(WinUser.HMONITOR hMonitor, int dpiType, IntByReference dpiX, IntByReference dpiY) {
|
||||
if (GetDpiForMonitor != null) {
|
||||
// HRESULT GetDpiForMonitor(HMONITOR hmonitor, MONITOR_DPI_TYPE dpiType, UINT *dpiX, UINT *dpiY);
|
||||
return (WinNT.HRESULT) GetDpiForMonitor.invoke(WinNT.HRESULT.class, new Object[]{hMonitor.getPointer(), dpiType, dpiX, dpiY});
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* Copyright 2017 dorkbox, llc
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package dorkbox.jna.windows;
|
||||
|
||||
import dorkbox.jna.JNA;
|
||||
import dorkbox.jna.windows.structs.NOTIFYICONDATA;
|
||||
|
||||
public
|
||||
class Shell32 {
|
||||
static {
|
||||
JNA.register("shell32", Shell32.class);
|
||||
}
|
||||
|
||||
static public final int NIM_ADD = 0x0;
|
||||
static public final int NIM_MODIFY = 0x1;
|
||||
static public final int NIM_DELETE = 0x2;
|
||||
|
||||
public static native
|
||||
boolean Shell_NotifyIcon(int dwMessage, NOTIFYICONDATA lpdata);
|
||||
}
|
|
@ -0,0 +1,173 @@
|
|||
/*
|
||||
* Copyright 2015 dorkbox, llc
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package dorkbox.jna.windows;
|
||||
|
||||
import static com.sun.jna.platform.win32.WinDef.HDC;
|
||||
import static com.sun.jna.platform.win32.WinDef.HICON;
|
||||
import static com.sun.jna.platform.win32.WinDef.HINSTANCE;
|
||||
import static com.sun.jna.platform.win32.WinDef.HMENU;
|
||||
import static com.sun.jna.platform.win32.WinDef.HWND;
|
||||
import static com.sun.jna.platform.win32.WinDef.LPARAM;
|
||||
import static com.sun.jna.platform.win32.WinDef.LRESULT;
|
||||
import static com.sun.jna.platform.win32.WinDef.POINT;
|
||||
import static com.sun.jna.platform.win32.WinDef.WPARAM;
|
||||
|
||||
import com.sun.jna.Callback;
|
||||
import com.sun.jna.Pointer;
|
||||
import com.sun.jna.WString;
|
||||
import com.sun.jna.platform.win32.WinNT;
|
||||
import com.sun.jna.platform.win32.WinUser.HMONITOR;
|
||||
|
||||
import dorkbox.jna.windows.structs.ICONINFO;
|
||||
import dorkbox.os.OS;
|
||||
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
public
|
||||
interface User32 {
|
||||
User32 User32 = OS.INSTANCE.is64bit() ? new User32_64() : new User32_32();
|
||||
|
||||
int GWL_WNDPROC = -4;
|
||||
|
||||
int WM_LBUTTONUP = 0x202;
|
||||
int WM_RBUTTONUP = 0x205;
|
||||
|
||||
/**
|
||||
* This is overridden by the 64-bit version to be SetWindowLongPtr instead.
|
||||
*/
|
||||
int SetWindowLong(HWND hWnd, int nIndex, Callback procedure);
|
||||
|
||||
/**
|
||||
* The GetSystemMetrics function retrieves various system metrics (widths
|
||||
* and heights of display elements) and system configuration settings. All
|
||||
* dimensions retrieved by GetSystemMetrics are in pixels.
|
||||
*
|
||||
* @param nIndex System metric or configuration setting to retrieve. This
|
||||
* parameter can be one of the following values. Note that all
|
||||
* SM_CX* values are widths and all SM_CY* values are heights.
|
||||
* Also note that all settings designed to return Boolean data
|
||||
* represent TRUE as any nonzero value, and FALSE as a zero
|
||||
* value.
|
||||
*
|
||||
* @return If the function succeeds, the return value is the requested
|
||||
* system metric or configuration setting. If the function fails,
|
||||
* the return value is zero. GetLastError does not provide extended
|
||||
* error information.
|
||||
*/
|
||||
int GetSystemMetrics(int nIndex);
|
||||
|
||||
/**
|
||||
* http://msdn.microsoft.com/en-us/library/windows/desktop/ms644950(v=vs.85).aspx
|
||||
*/
|
||||
LRESULT SendMessage(HWND hWnd, int Msg, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
/**
|
||||
* http://msdn.microsoft.com/en-us/library/windows/desktop/ms648062(v=vs.85).aspx
|
||||
*/
|
||||
HICON CreateIconIndirect(ICONINFO piconinfo);
|
||||
|
||||
/**
|
||||
* http://msdn.microsoft.com/en-us/library/windows/desktop/ms632682(v=vs.85).aspx
|
||||
*/
|
||||
boolean DestroyWindow(HWND hWnd);
|
||||
|
||||
/**
|
||||
* This function places a message in the message queue associated with the
|
||||
* thread that created the specified window and then returns without waiting
|
||||
* for the thread to process the message. Messages in a message queue are
|
||||
* retrieved by calls to the GetMessage or PeekMessage function.
|
||||
*
|
||||
* @param hWnd Handle to the window whose window procedure is to receive the
|
||||
* message.
|
||||
* @param msg Specifies the message to be posted.
|
||||
* @param wParam Specifies additional message-specific information.
|
||||
* @param lParam Specifies additional message-specific information.
|
||||
*/
|
||||
void PostMessage(HWND hWnd, int msg, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
/**
|
||||
* http://msdn.microsoft.com/en-us/library/windows/desktop/ms632680(v=vs.85).aspx
|
||||
*/
|
||||
HWND CreateWindowEx(int dwExStyle,
|
||||
String lpClassName,
|
||||
String lpWindowName,
|
||||
int dwStyle,
|
||||
int x,
|
||||
int y,
|
||||
int nWidth,
|
||||
int nHeight,
|
||||
HWND hWndParent,
|
||||
HMENU hMenu,
|
||||
HINSTANCE hInstance,
|
||||
WinNT.HANDLE lpParam);
|
||||
|
||||
|
||||
/**
|
||||
* http://msdn.microsoft.com/en-us/library/windows/desktop/ms644947(v=vs.85).aspx
|
||||
*/
|
||||
LRESULT DefWindowProc(HWND hWnd, int Msg, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
boolean GetMessage(MSG lpMsg, Pointer hWnd, int wMsgFilterMin, int wMsgFilterMax);
|
||||
|
||||
boolean TranslateMessage(MSG lpMsg);
|
||||
|
||||
boolean DispatchMessage(MSG lpMsg);
|
||||
|
||||
int RegisterWindowMessage(WString lpString);
|
||||
|
||||
/**
|
||||
* https://msdn.microsoft.com/en-us/library/windows/desktop/dd144871(v=vs.85).aspx
|
||||
*
|
||||
* This function retrieves a handle to a display device context (DC) for the
|
||||
* client area of the specified window. The display device context can be
|
||||
* used in subsequent graphics display interface (GDI) functions to draw in
|
||||
* the client area of the window.
|
||||
*
|
||||
* @param hWnd Handle to the window whose device context is to be retrieved.
|
||||
* If this value is NULL, GetDC retrieves the device context for
|
||||
* the entire screen.
|
||||
*
|
||||
* @return The handle the device context for the specified window's client
|
||||
* area indicates success. NULL indicates failure. To get extended
|
||||
* error information, call GetLastError.
|
||||
*/
|
||||
HDC GetDC(HWND hWnd);
|
||||
|
||||
/**
|
||||
* https://msdn.microsoft.com/en-us/library/windows/desktop/dd162920(v=vs.85).aspx
|
||||
*
|
||||
* This function releases a device context (DC), freeing it for use by other
|
||||
* applications. The effect of ReleaseDC depends on the type of device
|
||||
* context.
|
||||
*
|
||||
* @param hWnd Handle to the window whose device context is to be released.
|
||||
* @param hDC Handle to the device context to be released.
|
||||
*
|
||||
* @return The return value specifies whether the device context is
|
||||
* released. 1 indicates that the device context is released. Zero
|
||||
* indicates that the device context is not released.
|
||||
*/
|
||||
int ReleaseDC(HWND hWnd, HDC hDC);
|
||||
|
||||
/**
|
||||
* https://msdn.microsoft.com/en-us/library/windows/desktop/ms648390(v=vs.85).aspx
|
||||
*/
|
||||
boolean GetCursorPos(POINT point);
|
||||
|
||||
/**
|
||||
* https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-monitorfrompoint
|
||||
*/
|
||||
HMONITOR MonitorFromPoint(POINT.ByValue pt, int dwFlags);
|
||||
}
|
|
@ -0,0 +1,125 @@
|
|||
/*
|
||||
* Copyright 2017 dorkbox, llc
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package dorkbox.jna.windows;
|
||||
|
||||
import static com.sun.jna.platform.win32.WinDef.HDC;
|
||||
import static com.sun.jna.platform.win32.WinDef.HICON;
|
||||
import static com.sun.jna.platform.win32.WinDef.HINSTANCE;
|
||||
import static com.sun.jna.platform.win32.WinDef.HMENU;
|
||||
import static com.sun.jna.platform.win32.WinDef.HWND;
|
||||
import static com.sun.jna.platform.win32.WinDef.LPARAM;
|
||||
import static com.sun.jna.platform.win32.WinDef.LRESULT;
|
||||
import static com.sun.jna.platform.win32.WinDef.POINT;
|
||||
import static com.sun.jna.platform.win32.WinDef.WPARAM;
|
||||
|
||||
import com.sun.jna.Callback;
|
||||
import com.sun.jna.Pointer;
|
||||
import com.sun.jna.WString;
|
||||
import com.sun.jna.platform.win32.WinNT;
|
||||
import com.sun.jna.platform.win32.WinUser.HMONITOR;
|
||||
|
||||
import dorkbox.jna.JNA;
|
||||
import dorkbox.jna.windows.structs.ICONINFO;
|
||||
|
||||
/**
|
||||
* On first glance, this appears to be unnecessary to have a DirectMapping class implement an interface - however this is so different
|
||||
* methods can be overridden by the correct 64bit versions, otherwise multiple copies of this library would have to be loaded (one for
|
||||
* "normal", and another for the "special case").
|
||||
*
|
||||
* Doing it this way greatly simplifies the API while maintaining Direct Mapping, at the cost of a slightly more complex code hierarchy.
|
||||
*/
|
||||
public
|
||||
class User32_32 implements User32 {
|
||||
static {
|
||||
JNA.register("user32", User32_32.class);
|
||||
}
|
||||
|
||||
// is replaced by the 64bit version
|
||||
@Override
|
||||
public native
|
||||
int SetWindowLong(HWND hWnd, int nIndex, Callback procedure);
|
||||
|
||||
@Override
|
||||
public native
|
||||
int GetSystemMetrics(final int nIndex);
|
||||
|
||||
@Override
|
||||
public native
|
||||
LRESULT SendMessage(final HWND hWnd, final int Msg, final WPARAM wParam, final LPARAM lParam);
|
||||
|
||||
@Override
|
||||
public native
|
||||
HICON CreateIconIndirect(final ICONINFO piconinfo);
|
||||
|
||||
@Override
|
||||
public native
|
||||
boolean DestroyWindow(final HWND hWnd);
|
||||
|
||||
@Override
|
||||
public native
|
||||
void PostMessage(final HWND hWnd, final int msg, final WPARAM wParam, final LPARAM lParam);
|
||||
|
||||
@Override
|
||||
public native
|
||||
HWND CreateWindowEx(final int dwExStyle,
|
||||
final String lpClassName,
|
||||
final String lpWindowName,
|
||||
final int dwStyle,
|
||||
final int x,
|
||||
final int y,
|
||||
final int nWidth,
|
||||
final int nHeight,
|
||||
final HWND hWndParent,
|
||||
final HMENU hMenu,
|
||||
final HINSTANCE hInstance,
|
||||
final WinNT.HANDLE lpParam);
|
||||
|
||||
@Override
|
||||
public native
|
||||
LRESULT DefWindowProc(final HWND hWnd, final int Msg, final WPARAM wParam, final LPARAM lParam);
|
||||
|
||||
@Override
|
||||
public native
|
||||
boolean GetMessage(final MSG lpMsg, final Pointer hWnd, final int wMsgFilterMin, final int wMsgFilterMax);
|
||||
|
||||
@Override
|
||||
public native
|
||||
boolean TranslateMessage(final MSG lpMsg);
|
||||
|
||||
@Override
|
||||
public native
|
||||
boolean DispatchMessage(final MSG lpMsg);
|
||||
|
||||
@Override
|
||||
public native
|
||||
int RegisterWindowMessage(final WString lpString);
|
||||
|
||||
@Override
|
||||
public native
|
||||
HDC GetDC(final HWND hWnd);
|
||||
|
||||
@Override
|
||||
public native
|
||||
int ReleaseDC(final HWND hWnd, final HDC hDC);
|
||||
|
||||
@Override
|
||||
public native
|
||||
boolean GetCursorPos(final POINT point);
|
||||
|
||||
@Override
|
||||
public native
|
||||
HMONITOR MonitorFromPoint(POINT.ByValue pt, int dwFlags);
|
||||
}
|
|
@ -0,0 +1,130 @@
|
|||
/*
|
||||
* Copyright 2017 dorkbox, llc
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package dorkbox.jna.windows;
|
||||
|
||||
import static com.sun.jna.platform.win32.WinDef.HDC;
|
||||
import static com.sun.jna.platform.win32.WinDef.HICON;
|
||||
import static com.sun.jna.platform.win32.WinDef.HINSTANCE;
|
||||
import static com.sun.jna.platform.win32.WinDef.HMENU;
|
||||
import static com.sun.jna.platform.win32.WinDef.HWND;
|
||||
import static com.sun.jna.platform.win32.WinDef.LPARAM;
|
||||
import static com.sun.jna.platform.win32.WinDef.LRESULT;
|
||||
import static com.sun.jna.platform.win32.WinDef.POINT;
|
||||
import static com.sun.jna.platform.win32.WinDef.WPARAM;
|
||||
|
||||
import com.sun.jna.Callback;
|
||||
import com.sun.jna.Pointer;
|
||||
import com.sun.jna.WString;
|
||||
import com.sun.jna.platform.win32.WinNT;
|
||||
import com.sun.jna.platform.win32.WinUser.HMONITOR;
|
||||
|
||||
import dorkbox.jna.JNA;
|
||||
import dorkbox.jna.windows.structs.ICONINFO;
|
||||
|
||||
/**
|
||||
* On first glance, this appears to be unnecessary to have a DirectMapping class implement an interface - however this is so different
|
||||
* methods can be overridden by the correct 64bit versions, otherwise multiple copies of this library would have to be loaded (one for
|
||||
* "normal", and another for the "special case").
|
||||
*
|
||||
* Doing it this way greatly simplifies the API while maintaining Direct Mapping, at the cost of a slightly more complex code hierarchy.
|
||||
*/
|
||||
public
|
||||
class User32_64 implements User32 {
|
||||
static {
|
||||
JNA.register("user32", User32_64.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public
|
||||
int SetWindowLong(HWND hWnd, int nIndex, Callback procedure) {
|
||||
return SetWindowLongPtr(hWnd, nIndex, procedure);
|
||||
}
|
||||
|
||||
// should be used instead of SetWindowLong for 64 versions
|
||||
public native
|
||||
int SetWindowLongPtr(HWND hWnd, int nIndex, Callback procedure);
|
||||
|
||||
@Override
|
||||
public native
|
||||
int GetSystemMetrics(final int nIndex);
|
||||
|
||||
@Override
|
||||
public native
|
||||
LRESULT SendMessage(final HWND hWnd, final int Msg, final WPARAM wParam, final LPARAM lParam);
|
||||
|
||||
@Override
|
||||
public native
|
||||
HICON CreateIconIndirect(final ICONINFO piconinfo);
|
||||
|
||||
@Override
|
||||
public native
|
||||
boolean DestroyWindow(final HWND hWnd);
|
||||
|
||||
@Override
|
||||
public native
|
||||
void PostMessage(final HWND hWnd, final int msg, final WPARAM wParam, final LPARAM lParam);
|
||||
|
||||
@Override
|
||||
public native
|
||||
HWND CreateWindowEx(final int dwExStyle,
|
||||
final String lpClassName,
|
||||
final String lpWindowName,
|
||||
final int dwStyle,
|
||||
final int x,
|
||||
final int y,
|
||||
final int nWidth,
|
||||
final int nHeight,
|
||||
final HWND hWndParent,
|
||||
final HMENU hMenu,
|
||||
final HINSTANCE hInstance,
|
||||
final WinNT.HANDLE lpParam);
|
||||
|
||||
@Override
|
||||
public native
|
||||
LRESULT DefWindowProc(final HWND hWnd, final int Msg, final WPARAM wParam, final LPARAM lParam);
|
||||
|
||||
@Override
|
||||
public native
|
||||
boolean GetMessage(final MSG lpMsg, final Pointer hWnd, final int wMsgFilterMin, final int wMsgFilterMax);
|
||||
|
||||
@Override
|
||||
public native
|
||||
boolean TranslateMessage(final MSG lpMsg);
|
||||
|
||||
@Override
|
||||
public native
|
||||
boolean DispatchMessage(final MSG lpMsg);
|
||||
|
||||
@Override
|
||||
public native
|
||||
int RegisterWindowMessage(final WString lpString);
|
||||
|
||||
@Override
|
||||
public native
|
||||
HDC GetDC(final HWND hWnd);
|
||||
|
||||
@Override
|
||||
public native
|
||||
int ReleaseDC(final HWND hWnd, final HDC hDC);
|
||||
|
||||
@Override
|
||||
public native
|
||||
boolean GetCursorPos(final POINT point);
|
||||
|
||||
@Override
|
||||
public native
|
||||
HMONITOR MonitorFromPoint(POINT.ByValue pt, int dwFlags);
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* Copyright 2017 dorkbox, llc
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package dorkbox.jna.windows;
|
||||
|
||||
import static com.sun.jna.platform.win32.WinDef.HWND;
|
||||
import static com.sun.jna.platform.win32.WinDef.LPARAM;
|
||||
import static com.sun.jna.platform.win32.WinDef.LRESULT;
|
||||
import static com.sun.jna.platform.win32.WinDef.WPARAM;
|
||||
|
||||
import com.sun.jna.win32.StdCallLibrary;
|
||||
|
||||
public
|
||||
interface WNDPROC extends StdCallLibrary.StdCallCallback {
|
||||
LRESULT callback(HWND hWnd, int uMsg, WPARAM uParam, LPARAM lParam);
|
||||
}
|
|
@ -0,0 +1,202 @@
|
|||
/*
|
||||
* Copyright 2017 dorkbox, llc
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package dorkbox.jna.windows;
|
||||
|
||||
import static com.sun.jna.platform.win32.WinDef.HWND;
|
||||
import static com.sun.jna.platform.win32.WinDef.LPARAM;
|
||||
import static com.sun.jna.platform.win32.WinDef.LRESULT;
|
||||
import static com.sun.jna.platform.win32.WinDef.WPARAM;
|
||||
import static com.sun.jna.platform.win32.WinUser.WM_QUIT;
|
||||
import static dorkbox.jna.windows.User32.User32;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.sun.jna.WString;
|
||||
import com.sun.jna.platform.win32.WinUser;
|
||||
|
||||
@SuppressWarnings({"Convert2Lambda", "UnusedAssignment", "Convert2Diamond", "FieldCanBeLocal", "unused"})
|
||||
public
|
||||
class WindowsEventDispatch implements Runnable {
|
||||
private static final Logger logger = LoggerFactory.getLogger(WindowsEventDispatch.class);
|
||||
|
||||
private static final String NAME = "WindowsEventDispatch_";
|
||||
private static final AtomicInteger COUNT = new AtomicInteger(0);
|
||||
|
||||
public static final int WM_TASKBARCREATED = User32.RegisterWindowMessage(new WString("TaskbarCreated"));
|
||||
public static final int WM_COMMAND = 0x0111;
|
||||
public static final int WM_SHELLNOTIFY = WinUser.WM_USER + 1;
|
||||
public static final int WM_MEASUREITEM = 44;
|
||||
public static final int WM_DRAWITEM = 43;
|
||||
|
||||
public static final int MF_POPUP = 0x00000010;
|
||||
|
||||
|
||||
private final String name = NAME + COUNT.getAndIncrement();
|
||||
private final Map<Integer, List<Listener>> messageIDs = new HashMap<Integer, List<Listener>>();
|
||||
|
||||
private final Object lock = new Object();
|
||||
|
||||
private Thread dispatchThread;
|
||||
|
||||
// keep these around to prevent GC
|
||||
private WNDPROC WndProc;
|
||||
|
||||
// used to dispatch messages
|
||||
private volatile HWND hWnd;
|
||||
|
||||
|
||||
private
|
||||
WindowsEventDispatch() {
|
||||
}
|
||||
|
||||
public static
|
||||
WindowsEventDispatch start() {
|
||||
WindowsEventDispatch edt = new WindowsEventDispatch();
|
||||
|
||||
synchronized (edt.lock) {
|
||||
edt.start_();
|
||||
|
||||
try {
|
||||
// wait for the dispatch thread to start if we aren't started yet, but requested it
|
||||
edt.lock.wait();
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
return edt;
|
||||
}
|
||||
|
||||
public
|
||||
HWND get() {
|
||||
return hWnd;
|
||||
}
|
||||
|
||||
// always from inside lock!
|
||||
private
|
||||
void start_() {
|
||||
dispatchThread = new Thread(this, name);
|
||||
dispatchThread.start();
|
||||
}
|
||||
|
||||
public void
|
||||
stop() {
|
||||
synchronized (lock) {
|
||||
if (hWnd != null) {
|
||||
User32.PostMessage(hWnd, WM_QUIT, new WPARAM(0), new LPARAM(0));
|
||||
|
||||
try {
|
||||
// wait for the dispatch thread to quit (but only if we are not on the dispatch thread)
|
||||
if (!Thread.currentThread().equals(dispatchThread)) {
|
||||
dispatchThread.join();
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("Java8MapApi")
|
||||
public
|
||||
void addListener(final int messageId, final Listener listener) {
|
||||
synchronized (messageIDs) {
|
||||
List<Listener> listeners = messageIDs.get(messageId);
|
||||
if (listeners == null) {
|
||||
listeners = new ArrayList<Listener>();
|
||||
messageIDs.put(messageId, listeners);
|
||||
}
|
||||
|
||||
listeners.add(listener);
|
||||
}
|
||||
}
|
||||
|
||||
public
|
||||
void removeListener(final Listener listener) {
|
||||
synchronized (messageIDs) {
|
||||
for (Map.Entry<Integer, List<Listener>> entry : messageIDs.entrySet()) {
|
||||
List<Listener> value = entry.getValue();
|
||||
if (value.remove(listener)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public
|
||||
void run() {
|
||||
WndProc = new WNDPROC() {
|
||||
@Override
|
||||
public
|
||||
LRESULT callback(HWND hWnd, int msg, WPARAM wParam, LPARAM lParam) {
|
||||
List<Listener> listeners = null;
|
||||
synchronized (messageIDs) {
|
||||
listeners = messageIDs.get(msg);
|
||||
if (listeners != null) {
|
||||
// make a copy, in case a listener action modifies the message listener
|
||||
listeners = new ArrayList<Listener>(listeners);
|
||||
}
|
||||
}
|
||||
|
||||
if (listeners != null) {
|
||||
for (final Listener listener : listeners) {
|
||||
if (listener != null) {
|
||||
try {
|
||||
listener.run(hWnd, wParam, lParam);
|
||||
} catch (Exception e) {
|
||||
logger.error("Error during listener execution.", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return User32.DefWindowProc(hWnd, msg, wParam, lParam);
|
||||
}
|
||||
};
|
||||
|
||||
hWnd = User32.CreateWindowEx(0, "STATIC", name, 0, 0, 0, 0, 0, null, null, null, null);
|
||||
if (hWnd == null) {
|
||||
throw new GetLastErrorException();
|
||||
}
|
||||
|
||||
User32.SetWindowLong(hWnd, User32.GWL_WNDPROC, WndProc);
|
||||
|
||||
synchronized (lock) {
|
||||
lock.notifyAll();
|
||||
}
|
||||
|
||||
MSG msg = new MSG();
|
||||
while (User32.GetMessage(msg, null, 0, 0)) {
|
||||
User32.TranslateMessage(msg);
|
||||
User32.DispatchMessage(msg);
|
||||
}
|
||||
|
||||
if (hWnd != null) {
|
||||
if (!User32.DestroyWindow(hWnd)) {
|
||||
throw new GetLastErrorException();
|
||||
}
|
||||
hWnd = null;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
/*
|
||||
* Copyright 2021 dorkbox, llc
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package dorkbox.jna.windows;
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Copyright 2016 dorkbox, llc
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package dorkbox.jna.windows.structs;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import com.sun.jna.Structure;
|
||||
|
||||
/**
|
||||
* https://msdn.microsoft.com/en-us/library/ms682093%28VS.85%29.aspx
|
||||
*/
|
||||
public
|
||||
class CONSOLE_SCREEN_BUFFER_INFO extends Structure {
|
||||
|
||||
public COORD size = new COORD();
|
||||
public COORD cursorPosition = new COORD();
|
||||
public short attributes = (short) 0;
|
||||
public SMALL_RECT window = new SMALL_RECT();
|
||||
public COORD maximumWindowSize = new COORD();
|
||||
|
||||
@Override
|
||||
protected
|
||||
List<String> getFieldOrder() {
|
||||
return Arrays.asList("size", "cursorPosition", "attributes", "window", "maximumWindowSize");
|
||||
}
|
||||
|
||||
@Override
|
||||
public
|
||||
String toString() {
|
||||
return "Size: " + size + " CursorPos: " + cursorPosition + " Attribs: " + attributes + " Window: " + window + " MaxWindowSize: " +
|
||||
maximumWindowSize;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* Copyright 2016 dorkbox, llc
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package dorkbox.jna.windows.structs;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import com.sun.jna.Structure;
|
||||
|
||||
/**
|
||||
* https://msdn.microsoft.com/en-us/library/ms682119(v=vs.85).aspx
|
||||
*/
|
||||
public
|
||||
class COORD extends Structure {
|
||||
public short x;
|
||||
public short y;
|
||||
|
||||
public
|
||||
COORD.ByValue asValue() {
|
||||
COORD.ByValue copy = new COORD.ByValue();
|
||||
copy.x = this.x;
|
||||
copy.y = this.y;
|
||||
return copy;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected
|
||||
List<String> getFieldOrder() {
|
||||
return Arrays.asList("x", "y");
|
||||
}
|
||||
|
||||
@Override
|
||||
public
|
||||
String toString() {
|
||||
return x + ":" + y;
|
||||
}
|
||||
|
||||
|
||||
static public
|
||||
class ByValue extends COORD implements Structure.ByValue {}
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* Copyright 2016 dorkbox, llc
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package dorkbox.jna.windows.structs;
|
||||
|
||||
import com.sun.jna.Union;
|
||||
|
||||
public
|
||||
class CharUnion extends Union {
|
||||
public char unicodeChar;
|
||||
public byte asciiChar;
|
||||
|
||||
public
|
||||
CharUnion() {
|
||||
}
|
||||
|
||||
public
|
||||
CharUnion(char c) {
|
||||
setType(char.class);
|
||||
unicodeChar = c;
|
||||
}
|
||||
|
||||
public
|
||||
CharUnion(byte c) {
|
||||
setType(byte.class);
|
||||
asciiChar = c;
|
||||
}
|
||||
|
||||
public
|
||||
void set(char c) {
|
||||
setType(char.class);
|
||||
unicodeChar = c;
|
||||
}
|
||||
|
||||
public
|
||||
void set(byte c) {
|
||||
setType(byte.class);
|
||||
asciiChar = c;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* Copyright 2017 dorkbox, llc
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package dorkbox.jna.windows.structs;
|
||||
|
||||
import static com.sun.jna.platform.win32.WinDef.DWORD;
|
||||
import static com.sun.jna.platform.win32.WinDef.HBITMAP;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import com.sun.jna.Structure;
|
||||
|
||||
/**
|
||||
* http://msdn.microsoft.com/en-us/library/windows/desktop/ms648052(v=vs.85).aspx
|
||||
*/
|
||||
public
|
||||
class ICONINFO extends Structure {
|
||||
public boolean IsIcon;
|
||||
public DWORD xHotspot;
|
||||
public DWORD yHotspot;
|
||||
public HBITMAP MaskBitmap;
|
||||
public HBITMAP ColorBitmap;
|
||||
|
||||
|
||||
public
|
||||
ICONINFO() {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected
|
||||
List<String> getFieldOrder() {
|
||||
return Arrays.asList("IsIcon", "xHotspot", "yHotspot", "MaskBitmap", "ColorBitmap");
|
||||
}
|
||||
|
||||
public static
|
||||
class ByValue extends ICONINFO implements Structure.ByValue {}
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* Copyright 2016 dorkbox, llc
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package dorkbox.jna.windows.structs;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import com.sun.jna.Structure;
|
||||
import com.sun.jna.Union;
|
||||
|
||||
/**
|
||||
* https://msdn.microsoft.com/en-us/library/ms683499(v=VS.85).aspx
|
||||
*/
|
||||
public
|
||||
class INPUT_RECORD extends Structure {
|
||||
public static final short KEY_EVENT = 0x0001;
|
||||
public static final short MOUSE_EVENT = 0x0002;
|
||||
public short EventType;
|
||||
public EventUnion Event;
|
||||
|
||||
@Override
|
||||
public
|
||||
void read() {
|
||||
readField("EventType");
|
||||
switch (EventType) {
|
||||
case KEY_EVENT:
|
||||
Event.setType(KEY_EVENT_RECORD.class);
|
||||
break;
|
||||
case MOUSE_EVENT:
|
||||
Event.setType(MOUSE_EVENT_RECORD.class);
|
||||
break;
|
||||
}
|
||||
super.read();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected
|
||||
List<String> getFieldOrder() {
|
||||
return Arrays.asList("EventType", "Event");
|
||||
}
|
||||
|
||||
|
||||
static public
|
||||
class ByReference extends INPUT_RECORD implements Structure.ByReference {}
|
||||
|
||||
|
||||
public static
|
||||
class EventUnion extends Union {
|
||||
public KEY_EVENT_RECORD KeyEvent;
|
||||
public MOUSE_EVENT_RECORD MouseEvent;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Copyright 2016 dorkbox, llc
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package dorkbox.jna.windows.structs;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import com.sun.jna.Structure;
|
||||
|
||||
/**
|
||||
* https://msdn.microsoft.com/en-us/library/ms684166(v=VS.85).aspx
|
||||
*/
|
||||
public
|
||||
class KEY_EVENT_RECORD extends Structure {
|
||||
public boolean keyDown;
|
||||
public short repeatCount;
|
||||
public short virtualKeyCode;
|
||||
public short virtualScanCode;
|
||||
public CharUnion uChar;
|
||||
public int controlKeyState;
|
||||
|
||||
@Override
|
||||
protected
|
||||
List<String> getFieldOrder() {
|
||||
return Arrays.asList("keyDown", "repeatCount", "virtualKeyCode", "virtualScanCode", "uChar", "controlKeyState");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* Copyright 2016 dorkbox, llc
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package dorkbox.jna.windows.structs;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import com.sun.jna.Structure;
|
||||
|
||||
public
|
||||
class MOUSE_EVENT_RECORD extends Structure {
|
||||
public COORD mousePosition;
|
||||
public int buttonState;
|
||||
public int controlKeyState;
|
||||
public int eventFlags;
|
||||
|
||||
@Override
|
||||
protected
|
||||
List<String> getFieldOrder() {
|
||||
return Arrays.asList("mousePosition", "buttonState", "controlKeyState", "eventFlags");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,116 @@
|
|||
/*
|
||||
* Copyright 2017 dorkbox, llc
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package dorkbox.jna.windows.structs;
|
||||
|
||||
import static com.sun.jna.platform.win32.WinDef.HWND;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import com.sun.jna.Structure;
|
||||
import com.sun.jna.platform.win32.WinDef;
|
||||
|
||||
/**
|
||||
* http://msdn.microsoft.com/en-us/library/windows/desktop/bb773352(v=vs.85).aspx
|
||||
*/
|
||||
public class NOTIFYICONDATA extends Structure {
|
||||
static public final int NIF_MESSAGE = 0x1;
|
||||
static public final int NIF_ICON = 0x2;
|
||||
static public final int NIF_TIP = 0x4;
|
||||
static public final int NIF_STATE = 0x8;
|
||||
|
||||
static public final int NIF_INFO = 0x10;
|
||||
|
||||
static public final int NIIF_NONE = 0x0;
|
||||
static public final int NIIF_INFO = 0x1;
|
||||
static public final int NIIF_WARNING = 0x2;
|
||||
static public final int NIIF_ERROR = 0x3;
|
||||
static public final int NIIF_USER = 0x4;
|
||||
|
||||
public int cbSize;
|
||||
public HWND hWnd;
|
||||
public int uID;
|
||||
public int uFlags;
|
||||
public int uCallbackMessage;
|
||||
public WinDef.HICON hIcon;
|
||||
|
||||
public char[] szTip = new char[128];
|
||||
|
||||
public int dwState;
|
||||
public int dwStateMask;
|
||||
|
||||
public char[] szInfo = new char[256];
|
||||
public int uTimeoutOrVersion; // {UINT uTimeout; UINT uVersion;};
|
||||
|
||||
public char[] szInfoTitle = new char[64];
|
||||
public int dwInfoFlags;
|
||||
|
||||
public
|
||||
NOTIFYICONDATA() {
|
||||
cbSize = size();
|
||||
}
|
||||
|
||||
public
|
||||
void setTooltip(String s) {
|
||||
uFlags |= NIF_TIP;
|
||||
|
||||
System.arraycopy(s.toCharArray(), 0, szTip, 0, Math.min(s.length(), szTip.length));
|
||||
szTip[s.length()] = '\0';
|
||||
}
|
||||
|
||||
public
|
||||
void setBalloon(String title, String message, int millis, int niif) {
|
||||
uFlags |= NIF_INFO;
|
||||
|
||||
System.arraycopy(message.toCharArray(), 0, szInfo, 0, Math.min(message.length(), szInfo.length));
|
||||
szInfo[message.length()] = '\0';
|
||||
|
||||
uTimeoutOrVersion = millis;
|
||||
|
||||
System.arraycopy(title.toCharArray(), 0, szInfoTitle, 0, Math.min(title.length(), szInfoTitle.length));
|
||||
szInfoTitle[title.length()] = '\0';
|
||||
|
||||
dwInfoFlags = niif;
|
||||
}
|
||||
|
||||
public
|
||||
void setIcon(WinDef.HICON hIcon) {
|
||||
uFlags |= NIF_ICON;
|
||||
this.hIcon = hIcon;
|
||||
}
|
||||
|
||||
public void setCallback(int callback) {
|
||||
uFlags |= NIF_MESSAGE;
|
||||
uCallbackMessage = callback;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getFieldOrder () {
|
||||
return Arrays.asList("cbSize",
|
||||
"hWnd",
|
||||
"uID",
|
||||
"uFlags",
|
||||
"uCallbackMessage",
|
||||
"hIcon",
|
||||
"szTip",
|
||||
"dwState",
|
||||
"dwStateMask",
|
||||
"szInfo",
|
||||
"uTimeoutOrVersion",
|
||||
"szInfoTitle",
|
||||
"dwInfoFlags");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* Copyright 2016 dorkbox, llc
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package dorkbox.jna.windows.structs;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import com.sun.jna.Structure;
|
||||
|
||||
/**
|
||||
* https://msdn.microsoft.com/en-us/library/ms686311%28VS.85%29.aspx
|
||||
*/
|
||||
@SuppressWarnings("NumericCastThatLosesPrecision")
|
||||
public
|
||||
class SMALL_RECT extends Structure {
|
||||
public short left;
|
||||
public short top;
|
||||
public short right;
|
||||
public short bottom;
|
||||
|
||||
public
|
||||
short width() {
|
||||
return (short) (this.right - this.left);
|
||||
}
|
||||
|
||||
public
|
||||
short height() {
|
||||
return (short) (this.bottom - this.top);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected
|
||||
List<String> getFieldOrder() {
|
||||
return Arrays.asList("left", "top", "right", "bottom");
|
||||
}
|
||||
|
||||
@Override
|
||||
public
|
||||
String toString() {
|
||||
return "LTRB: " + left + "," + top + "," + right + "," + bottom;
|
||||
}
|
||||
|
||||
|
||||
static public
|
||||
class ByReference extends SMALL_RECT implements Structure.ByReference {}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
/*
|
||||
* Copyright 2021 dorkbox, llc
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package dorkbox.jna.windows.structs;
|
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* Copyright 2021 dorkbox, llc
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package dorkbox.jna;
|
||||
|
||||
/**
|
||||
* Required for intellij to not complain regarding `module-info` for a multi-release jar.
|
||||
* This file is completely ignored by the gradle build process
|
||||
*/
|
||||
public
|
||||
class EmptyClass {}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue