diff --git a/.firebaserc b/.firebaserc new file mode 100644 index 0000000..d1ca34f --- /dev/null +++ b/.firebaserc @@ -0,0 +1,5 @@ +{ + "projects": { + "default": "vectras-1678b" + } +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..aa724b7 --- /dev/null +++ b/.gitignore @@ -0,0 +1,15 @@ +*.iml +.gradle +/local.properties +/.idea/caches +/.idea/libraries +/.idea/modules.xml +/.idea/workspace.xml +/.idea/navEditor.xml +/.idea/assetWizardSettings.xml +.DS_Store +/build +/captures +.externalNativeBuild +.cxx +local.properties diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..26d3352 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,3 @@ +# Default ignored files +/shelf/ +/workspace.xml diff --git a/.idea/.name b/.idea/.name new file mode 100644 index 0000000..e81581e --- /dev/null +++ b/.idea/.name @@ -0,0 +1 @@ +Vectras \ No newline at end of file diff --git a/.idea/compiler.xml b/.idea/compiler.xml new file mode 100644 index 0000000..b589d56 --- /dev/null +++ b/.idea/compiler.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/deploymentTargetDropDown.xml b/.idea/deploymentTargetDropDown.xml new file mode 100644 index 0000000..1604e6d --- /dev/null +++ b/.idea/deploymentTargetDropDown.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..ae388c2 --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..8978d23 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..d159169 --- /dev/null +++ b/LICENSE @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..42afabf --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..c7504e7 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,78 @@ +plugins { + id 'com.android.application' + id 'com.google.gms.google-services' + id 'com.google.firebase.crashlytics' +} + +android { + signingConfigs { + release { + storeFile file('C:\\vectras\\Vectras-VM-Android\\vectras.jks') + storePassword 'epicstudios-vectras856' + keyAlias 'Vectras' + keyPassword 'xoureldeen856' + } + } + namespace 'com.vectras.vm' + compileSdk 34 + + defaultConfig { + applicationId "com.vectras.vm" + minSdk 21 + targetSdk 34 + versionCode 5 + versionName "2.1" + + ndk { abiFilters "armeabi-v7a","arm64-v8a", "x86", "x86_64" } + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + signingConfig signingConfigs.release + multiDexEnabled true + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + compileOptions { + sourceCompatibility JavaVersion.VERSION_17 + targetCompatibility JavaVersion.VERSION_17 + } + buildFeatures { + viewBinding true + } + sourceSets { + main { + jniLibs.srcDirs = ['src/main/jniLibs'] + } + } +} + +dependencies { + implementation 'androidx.appcompat:appcompat:1.6.1' + implementation 'com.google.android.material:material:1.11.0' + implementation 'androidx.constraintlayout:constraintlayout:2.1.4' + implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.6.2' + implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2' + implementation 'androidx.legacy:legacy-support-v4:1.0.0' + implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.1.0" + implementation 'androidx.navigation:navigation-fragment:2.7.6' + implementation 'androidx.navigation:navigation-ui:2.7.6' + implementation "androidx.preference:preference:1.2.1" + implementation 'com.github.bumptech.glide:glide:4.16.0' + implementation platform('com.google.firebase:firebase-bom:32.3.1') + implementation 'com.google.firebase:firebase-analytics' + implementation("com.google.firebase:firebase-auth") + implementation("com.google.firebase:firebase-database") + implementation 'com.google.firebase:firebase-storage' + implementation("com.google.android.gms:play-services-auth:20.7.0") + implementation("com.google.firebase:firebase-crashlytics") + implementation("com.google.android.gms:play-services-auth:20.7.0") + implementation 'com.google.android.gms:play-services-ads:22.6.0' + implementation 'com.airbnb.android:lottie:6.2.0' + implementation 'androidx.annotation:annotation:1.7.1' + testImplementation 'junit:junit:4.13.2' + androidTestImplementation 'androidx.test.ext:junit:1.1.5' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1' +} \ No newline at end of file diff --git a/app/google-services.json b/app/google-services.json new file mode 100644 index 0000000..4166f4a --- /dev/null +++ b/app/google-services.json @@ -0,0 +1,69 @@ +{ + "project_info": { + "project_number": "503162397535", + "firebase_url": "https://vectras-1678b-default-rtdb.firebaseio.com", + "project_id": "vectras-1678b", + "storage_bucket": "vectras-1678b.appspot.com" + }, + "client": [ + { + "client_info": { + "mobilesdk_app_id": "1:503162397535:android:736d8a117fdd7053a24cea", + "android_client_info": { + "package_name": "com.epicstudios.vectras" + } + }, + "oauth_client": [ + { + "client_id": "503162397535-889qblq47cgopc7e9ie7j140bm8i7cv2.apps.googleusercontent.com", + "client_type": 3 + } + ], + "api_key": [ + { + "current_key": "AIzaSyArdgVBdPexxwdZHveVbu5hjf5UnEDwTGs" + } + ], + "services": { + "appinvite_service": { + "other_platform_oauth_client": [ + { + "client_id": "503162397535-889qblq47cgopc7e9ie7j140bm8i7cv2.apps.googleusercontent.com", + "client_type": 3 + } + ] + } + } + }, + { + "client_info": { + "mobilesdk_app_id": "1:503162397535:android:7e9fe9a876827ce5a24cea", + "android_client_info": { + "package_name": "com.vectras.vm" + } + }, + "oauth_client": [ + { + "client_id": "503162397535-889qblq47cgopc7e9ie7j140bm8i7cv2.apps.googleusercontent.com", + "client_type": 3 + } + ], + "api_key": [ + { + "current_key": "AIzaSyArdgVBdPexxwdZHveVbu5hjf5UnEDwTGs" + } + ], + "services": { + "appinvite_service": { + "other_platform_oauth_client": [ + { + "client_id": "503162397535-889qblq47cgopc7e9ie7j140bm8i7cv2.apps.googleusercontent.com", + "client_type": 3 + } + ] + } + } + } + ], + "configuration_version": "1" +} \ No newline at end of file diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..481bb43 --- /dev/null +++ b/app/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile \ No newline at end of file diff --git a/app/src/androidTest/java/com/vectras/vm/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/vectras/vm/ExampleInstrumentedTest.java new file mode 100644 index 0000000..73b53ed --- /dev/null +++ b/app/src/androidTest/java/com/vectras/vm/ExampleInstrumentedTest.java @@ -0,0 +1,26 @@ +package com.vectras.vm; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + assertEquals("com.vectras.vm", appContext.getPackageName()); + } +} \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..09bf96c --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,136 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/roms/QEMU,cgthree.bin b/app/src/main/assets/roms/QEMU,cgthree.bin new file mode 100644 index 0000000..6fec946 Binary files /dev/null and b/app/src/main/assets/roms/QEMU,cgthree.bin differ diff --git a/app/src/main/assets/roms/QEMU,tcx.bin b/app/src/main/assets/roms/QEMU,tcx.bin new file mode 100644 index 0000000..d79cc1f Binary files /dev/null and b/app/src/main/assets/roms/QEMU,tcx.bin differ diff --git a/app/src/main/assets/roms/README b/app/src/main/assets/roms/README new file mode 100644 index 0000000..fa8b58b --- /dev/null +++ b/app/src/main/assets/roms/README @@ -0,0 +1,73 @@ +- SeaBIOS (bios.bin) is the successor of pc bios. + See http://www.seabios.org/ for more information. + +- The VGA BIOS and the Cirrus VGA BIOS come from the LGPL VGA bios + project (http://www.nongnu.org/vgabios/). + +- OpenBIOS (http://www.openbios.org/) is a free (GPL v2) portable + firmware implementation. The goal is to implement a 100% IEEE + 1275-1994 (referred to as Open Firmware) compliant firmware. + The included images for PowerPC (for 32 and 64 bit PPC CPUs), + Sparc32 (including QEMU,tcx.bin and QEMU,cgthree.bin) and Sparc64 are built + from OpenBIOS SVN revision 1280. + +- SLOF (Slimline Open Firmware) is a free IEEE 1275 Open Firmware + implementation for certain IBM POWER hardware. The sources are at + https://github.com/aik/SLOF, and the image currently in qemu is + built from git tag qemu-slof-20200717. + +- sgabios (the Serial Graphics Adapter option ROM) provides a means for + legacy x86 software to communicate with an attached serial console as + if a video card were attached. The master sources reside in a subversion + repository at http://sgabios.googlecode.com/svn/trunk. A git mirror is + available at https://git.qemu.org/git/sgabios.git. + +- The PXE roms come from the iPXE project. Built with BANNER_TIME 0. + Sources available at http://ipxe.org. Vendor:Device ID -> ROM mapping: + + 8086:100e -> pxe-e1000.rom + 8086:1209 -> pxe-eepro100.rom + 1050:0940 -> pxe-ne2k_pci.rom + 1022:2000 -> pxe-pcnet.rom + 10ec:8139 -> pxe-rtl8139.rom + 1af4:1000 -> pxe-virtio.rom + +- The sources for the Alpha palcode image is available from: + https://github.com/rth7680/qemu-palcode.git + +- The u-boot binary for e500 comes from the upstream denx u-boot project where + it was compiled using the qemu-ppce500 target. + A git mirror is available at: https://git.qemu.org/git/u-boot.git + The hash used to compile the current version is: 2072e72 + +- Skiboot (https://github.com/open-power/skiboot/) is an OPAL + (OpenPower Abstraction Layer) firmware for OpenPOWER systems. It can + run an hypervisor OS or simply a host OS on the "baremetal" + platform, also known as the PowerNV (Non-Virtualized) platform. + +- QemuMacDrivers (https://github.com/ozbenh/QemuMacDrivers) is a project to + provide virtualised drivers for PPC MacOS guests. + +- The "edk2-*.fd.bz2" images are platform firmware binaries and matching UEFI + variable store templates built from the TianoCore community's EFI Development + Kit II project + . The images + were built at git tag "edk2-stable201905". The firmware binaries bundle parts + of the OpenSSL project, at git tag "OpenSSL_1_1_1b" (the OpenSSL tag is a + function of the edk2 tag). Parts of the Berkeley SoftFloat library are + bundled as well, at Release 3e plus a subsequent typo fix (commit + b64af41c3276f97f0e181920400ee056b9c88037), as an OpenSSL dependency on 32-bit + ARM. Licensing information is given in "edk2-licenses.txt". The image files + are described by the JSON documents in the "pc-bios/descriptors" directory, + which conform to the "docs/interop/firmware.json" schema. + +- OpenSBI (https://github.com/riscv/opensbi) aims to provide an open-source + reference implementation of the RISC-V Supervisor Binary Interface (SBI) + specifications for platform-specific firmwares executing in M-mode. For all + supported platforms, OpenSBI provides several runtime firmware examples. + These example firmwares can be used to replace the legacy riscv-pk bootloader + and enable the use of well-known bootloaders such as U-Boot. + OpenSBI is distributed under the terms of the BSD 2-clause license + ("Simplified BSD License" or "FreeBSD License", SPDX: BSD-2-Clause). OpenSBI + source code also contains code reused from other projects desribed here: + https://github.com/riscv/opensbi/blob/master/ThirdPartyNotices.md. diff --git a/app/src/main/assets/roms/bios-256k.bin b/app/src/main/assets/roms/bios-256k.bin new file mode 100644 index 0000000..8fd4290 Binary files /dev/null and b/app/src/main/assets/roms/bios-256k.bin differ diff --git a/app/src/main/assets/roms/bios-microvm.bin b/app/src/main/assets/roms/bios-microvm.bin new file mode 100644 index 0000000..45eabc5 Binary files /dev/null and b/app/src/main/assets/roms/bios-microvm.bin differ diff --git a/app/src/main/assets/roms/bios.bin b/app/src/main/assets/roms/bios.bin new file mode 100644 index 0000000..528b8ab Binary files /dev/null and b/app/src/main/assets/roms/bios.bin differ diff --git a/app/src/main/assets/roms/efi-e1000.rom b/app/src/main/assets/roms/efi-e1000.rom new file mode 100644 index 0000000..6f088d4 Binary files /dev/null and b/app/src/main/assets/roms/efi-e1000.rom differ diff --git a/app/src/main/assets/roms/efi-e1000e.rom b/app/src/main/assets/roms/efi-e1000e.rom new file mode 100644 index 0000000..f536bdb Binary files /dev/null and b/app/src/main/assets/roms/efi-e1000e.rom differ diff --git a/app/src/main/assets/roms/efi-eepro100.rom b/app/src/main/assets/roms/efi-eepro100.rom new file mode 100644 index 0000000..64d8891 Binary files /dev/null and b/app/src/main/assets/roms/efi-eepro100.rom differ diff --git a/app/src/main/assets/roms/efi-ne2k_pci.rom b/app/src/main/assets/roms/efi-ne2k_pci.rom new file mode 100644 index 0000000..02ad0cb Binary files /dev/null and b/app/src/main/assets/roms/efi-ne2k_pci.rom differ diff --git a/app/src/main/assets/roms/efi-pcnet.rom b/app/src/main/assets/roms/efi-pcnet.rom new file mode 100644 index 0000000..88d25fa Binary files /dev/null and b/app/src/main/assets/roms/efi-pcnet.rom differ diff --git a/app/src/main/assets/roms/efi-rtl8139.rom b/app/src/main/assets/roms/efi-rtl8139.rom new file mode 100644 index 0000000..53f125e Binary files /dev/null and b/app/src/main/assets/roms/efi-rtl8139.rom differ diff --git a/app/src/main/assets/roms/efi-virtio.rom b/app/src/main/assets/roms/efi-virtio.rom new file mode 100644 index 0000000..a87321e Binary files /dev/null and b/app/src/main/assets/roms/efi-virtio.rom differ diff --git a/app/src/main/assets/roms/efi-vmxnet3.rom b/app/src/main/assets/roms/efi-vmxnet3.rom new file mode 100644 index 0000000..d017caf Binary files /dev/null and b/app/src/main/assets/roms/efi-vmxnet3.rom differ diff --git a/app/src/main/assets/roms/etc/resolv.conf b/app/src/main/assets/roms/etc/resolv.conf new file mode 100644 index 0000000..b74b944 --- /dev/null +++ b/app/src/main/assets/roms/etc/resolv.conf @@ -0,0 +1,2 @@ +nameserver 8.8.8.8 + diff --git a/app/src/main/assets/roms/hppa-firmware.img b/app/src/main/assets/roms/hppa-firmware.img new file mode 100644 index 0000000..82d98b1 Binary files /dev/null and b/app/src/main/assets/roms/hppa-firmware.img differ diff --git a/app/src/main/assets/roms/keymaps/Makefile b/app/src/main/assets/roms/keymaps/Makefile new file mode 100644 index 0000000..76217b0 --- /dev/null +++ b/app/src/main/assets/roms/keymaps/Makefile @@ -0,0 +1,56 @@ + +KEYMAP := $(shell which qemu-keymap 2>/dev/null) + +MAPS := ar bepo cz da de de-ch en-us en-gb es et fi fo \ + fr fr-be fr-ca fr-ch \ + hr hu is it ja lt lv mk nl no pl pt pt-br ru th tr + +ar : MAP_FLAGS := -l ar +bepo : MAP_FLAGS := -l fr -v dvorak +cz : MAP_FLAGS := -l cz +da : MAP_FLAGS := -l dk +de : MAP_FLAGS := -l de -v nodeadkeys +de-ch : MAP_FLAGS := -l ch +en-us : MAP_FLAGS := -l us +en-gb : MAP_FLAGS := -l gb +es : MAP_FLAGS := -l es +et : MAP_FLAGS := -l et +fi : MAP_FLAGS := -l fi +fo : MAP_FLAGS := -l fo +fr : MAP_FLAGS := -l fr -v nodeadkeys +fr-be : MAP_FLAGS := -l be +fr-ca : MAP_FLAGS := -l ca -v fr +fr-ch : MAP_FLAGS := -l ch -v fr +hr : MAP_FLAGS := -l hr +hu : MAP_FLAGS := -l hu +is : MAP_FLAGS := -l is +it : MAP_FLAGS := -l it +ja : MAP_FLAGS := -l jp -m jp106 +lt : MAP_FLAGS := -l lt +lv : MAP_FLAGS := -l lv +mk : MAP_FLAGS := -l mk +nl : MAP_FLAGS := -l nl +no : MAP_FLAGS := -l no +pl : MAP_FLAGS := -l pl +pt : MAP_FLAGS := -l pt +pt-br : MAP_FLAGS := -l br +ru : MAP_FLAGS := -l ru +th : MAP_FLAGS := -l th +tr : MAP_FLAGS := -l tr + +ifeq ($(KEYMAP),) + +all: + @echo "nothing to do (qemu-keymap not found)" + +else + +all: $(MAPS) + +clean: + rm -f $(MAPS) + +$(MAPS): $(KEYMAP) Makefile + $(KEYMAP) -f $@ $(MAP_FLAGS) + +endif diff --git a/app/src/main/assets/roms/keymaps/ar b/app/src/main/assets/roms/keymaps/ar new file mode 100644 index 0000000..f62b297 --- /dev/null +++ b/app/src/main/assets/roms/keymaps/ar @@ -0,0 +1,796 @@ +# +# generated by qemu-keymap +# model : pc105 +# layout : ar +# variant : - +# options : - + +# name: "Arabic" + +# modifiers +# 0: Shift +# 1: Lock +# 2: Control +# 3: Mod1 +# 4: Mod2 +# 5: Mod3 +# 6: Mod4 +# 7: Mod5 +# 8: NumLock +# 9: Alt +# 10: LevelThree +# 11: LAlt +# 12: RAlt +# 13: RControl +# 14: LControl +# 15: ScrollLock +# 16: LevelFive +# 17: AltGr +# 18: Meta +# 19: Super +# 20: Hyper + +# evdev 1 (0x1), QKeyCode "esc", number 0x1 +Escape 0x01 + +# evdev 2 (0x2), QKeyCode "1", number 0x2 +1 0x02 +exclam 0x02 shift +Arabic_1 0x02 altgr + +# evdev 3 (0x3), QKeyCode "2", number 0x3 +2 0x03 +at 0x03 shift +Arabic_2 0x03 altgr + +# evdev 4 (0x4), QKeyCode "3", number 0x4 +3 0x04 +numbersign 0x04 shift +Arabic_3 0x04 altgr + +# evdev 5 (0x5), QKeyCode "4", number 0x5 +4 0x05 +dollar 0x05 shift +Arabic_4 0x05 altgr + +# evdev 6 (0x6), QKeyCode "5", number 0x6 +5 0x06 +percent 0x06 shift +Arabic_5 0x06 altgr +U2030 0x06 shift altgr + +# evdev 7 (0x7), QKeyCode "6", number 0x7 +6 0x07 +asciicircum 0x07 shift +Arabic_6 0x07 altgr + +# evdev 8 (0x8), QKeyCode "7", number 0x8 +7 0x08 +ampersand 0x08 shift +Arabic_7 0x08 altgr + +# evdev 9 (0x9), QKeyCode "8", number 0x9 +8 0x09 +asterisk 0x09 shift +Arabic_8 0x09 altgr + +# evdev 10 (0xa), QKeyCode "9", number 0xa +9 0x0a +parenright 0x0a shift +Arabic_9 0x0a altgr + +# evdev 11 (0xb), QKeyCode "0", number 0xb +0 0x0b +parenleft 0x0b shift +Arabic_0 0x0b altgr + +# evdev 12 (0xc), QKeyCode "minus", number 0xc +minus 0x0c +underscore 0x0c shift +endash 0x0c altgr +U2011 0x0c shift altgr + +# evdev 13 (0xd), QKeyCode "equal", number 0xd +equal 0x0d +plus 0x0d shift +notequal 0x0d altgr +approxeq 0x0d shift altgr + +# evdev 14 (0xe), QKeyCode "backspace", number 0xe +BackSpace 0x0e + +# evdev 15 (0xf), QKeyCode "tab", number 0xf +Tab 0x0f +ISO_Left_Tab 0x0f shift + +# evdev 16 (0x10), QKeyCode "q", number 0x10 +Arabic_dad 0x10 +Arabic_fatha 0x10 shift +U2066 0x10 shift altgr + +# evdev 17 (0x11), QKeyCode "w", number 0x11 +Arabic_sad 0x11 +Arabic_fathatan 0x11 shift +U2067 0x11 shift altgr + +# evdev 18 (0x12), QKeyCode "e", number 0x12 +Arabic_theh 0x12 +Arabic_damma 0x12 shift +U2068 0x12 shift altgr + +# evdev 19 (0x13), QKeyCode "r", number 0x13 +Arabic_qaf 0x13 +Arabic_dammatan 0x13 shift +U2069 0x13 shift altgr + +# evdev 20 (0x14), QKeyCode "t", number 0x14 +Arabic_feh 0x14 +UFEF9 0x14 shift +Arabic_veh 0x14 altgr + +# evdev 21 (0x15), QKeyCode "y", number 0x15 +Arabic_ghain 0x15 +Arabic_hamzaunderalef 0x15 shift +U202A 0x15 shift altgr + +# evdev 22 (0x16), QKeyCode "u", number 0x16 +Arabic_ain 0x16 +grave 0x16 shift +U202B 0x16 shift altgr + +# evdev 23 (0x17), QKeyCode "i", number 0x17 +Arabic_ha 0x17 +division 0x17 shift +U202C 0x17 shift altgr + +# evdev 24 (0x18), QKeyCode "o", number 0x18 +Arabic_khah 0x18 +multiply 0x18 shift + +# evdev 25 (0x19), QKeyCode "p", number 0x19 +Arabic_hah 0x19 +Arabic_semicolon 0x19 shift +U200E 0x19 shift altgr + +# evdev 26 (0x1a), QKeyCode "bracket_left", number 0x1a +Arabic_jeem 0x1a +less 0x1a shift +Arabic_tcheh 0x1a altgr +U200F 0x1a shift altgr + +# evdev 27 (0x1b), QKeyCode "bracket_right", number 0x1b +Arabic_dal 0x1b +greater 0x1b shift +U061C 0x1b shift altgr + +# evdev 28 (0x1c), QKeyCode "ret", number 0x1c +Return 0x1c + +# evdev 29 (0x1d), QKeyCode "ctrl", number 0x1d +Control_L 0x1d + +# evdev 30 (0x1e), QKeyCode "a", number 0x1e +Arabic_sheen 0x1e +Arabic_kasra 0x1e shift + +# evdev 31 (0x1f), QKeyCode "s", number 0x1f +Arabic_seen 0x1f +Arabic_kasratan 0x1f shift + +# evdev 32 (0x20), QKeyCode "d", number 0x20 +Arabic_yeh 0x20 +bracketright 0x20 shift + +# evdev 33 (0x21), QKeyCode "f", number 0x21 +Arabic_beh 0x21 +bracketleft 0x21 shift +Arabic_peh 0x21 altgr + +# evdev 34 (0x22), QKeyCode "g", number 0x22 +Arabic_lam 0x22 +UFEF7 0x22 shift + +# evdev 35 (0x23), QKeyCode "h", number 0x23 +Arabic_alef 0x23 +Arabic_hamzaonalef 0x23 shift +U0671 0x23 altgr + +# evdev 36 (0x24), QKeyCode "j", number 0x24 +Arabic_teh 0x24 +Arabic_tatweel 0x24 shift + +# evdev 37 (0x25), QKeyCode "k", number 0x25 +Arabic_noon 0x25 +Arabic_comma 0x25 shift +U066B 0x25 altgr + +# evdev 38 (0x26), QKeyCode "l", number 0x26 +Arabic_meem 0x26 +slash 0x26 shift + +# evdev 39 (0x27), QKeyCode "semicolon", number 0x27 +Arabic_kaf 0x27 +colon 0x27 shift +Arabic_gaf 0x27 altgr + +# evdev 40 (0x28), QKeyCode "apostrophe", number 0x28 +Arabic_tah 0x28 +quotedbl 0x28 shift +U27E9 0x28 altgr +U200D 0x28 shift altgr + +# evdev 41 (0x29), QKeyCode "grave_accent", number 0x29 +Arabic_thal 0x29 +Arabic_shadda 0x29 shift +Arabic_percent 0x29 altgr +U0609 0x29 shift altgr + +# evdev 42 (0x2a), QKeyCode "shift", number 0x2a +Shift_L 0x2a + +# evdev 43 (0x2b), QKeyCode "backslash", number 0x2b +backslash 0x2b +ellipsis 0x2b shift +U27E8 0x2b altgr +U202F 0x2b shift altgr + +# evdev 44 (0x2c), QKeyCode "z", number 0x2c +Arabic_hamzaonyeh 0x2c +asciitilde 0x2c shift +guillemotright 0x2c altgr +U203A 0x2c shift altgr + +# evdev 45 (0x2d), QKeyCode "x", number 0x2d +Arabic_hamza 0x2d +Arabic_sukun 0x2d shift +guillemotleft 0x2d altgr +U2039 0x2d shift altgr + +# evdev 46 (0x2e), QKeyCode "c", number 0x2e +Arabic_hamzaonwaw 0x2e +braceright 0x2e shift + +# evdev 47 (0x2f), QKeyCode "v", number 0x2f +Arabic_ra 0x2f +braceleft 0x2f shift + +# evdev 48 (0x30), QKeyCode "b", number 0x30 +UFEFB 0x30 +UFEF5 0x30 shift + +# evdev 49 (0x31), QKeyCode "n", number 0x31 +Arabic_alefmaksura 0x31 +Arabic_maddaonalef 0x31 shift +Arabic_superscript_alef 0x31 altgr + +# evdev 50 (0x32), QKeyCode "m", number 0x32 +Arabic_tehmarbuta 0x32 +apostrophe 0x32 shift + +# evdev 51 (0x33), QKeyCode "comma", number 0x33 +Arabic_waw 0x33 +comma 0x33 shift +U066C 0x33 altgr + +# evdev 52 (0x34), QKeyCode "dot", number 0x34 +Arabic_zain 0x34 +period 0x34 shift +Arabic_jeh 0x34 altgr + +# evdev 53 (0x35), QKeyCode "slash", number 0x35 +Arabic_zah 0x35 +Arabic_question_mark 0x35 shift +U066D 0x35 altgr +U200C 0x35 shift altgr + +# evdev 54 (0x36), QKeyCode "shift_r", number 0x36 +Shift_R 0x36 + +# evdev 55 (0x37), QKeyCode "kp_multiply", number 0x37 +KP_Multiply 0x37 + +# evdev 56 (0x38), QKeyCode "alt", number 0x38 +Alt_L 0x38 +Meta_L 0x38 shift + +# evdev 57 (0x39), QKeyCode "spc", number 0x39 +space 0x39 + +# evdev 58 (0x3a), QKeyCode "caps_lock", number 0x3a +Caps_Lock 0x3a + +# evdev 59 (0x3b), QKeyCode "f1", number 0x3b +F1 0x3b + +# evdev 60 (0x3c), QKeyCode "f2", number 0x3c +F2 0x3c + +# evdev 61 (0x3d), QKeyCode "f3", number 0x3d +F3 0x3d + +# evdev 62 (0x3e), QKeyCode "f4", number 0x3e +F4 0x3e + +# evdev 63 (0x3f), QKeyCode "f5", number 0x3f +F5 0x3f + +# evdev 64 (0x40), QKeyCode "f6", number 0x40 +F6 0x40 + +# evdev 65 (0x41), QKeyCode "f7", number 0x41 +F7 0x41 + +# evdev 66 (0x42), QKeyCode "f8", number 0x42 +F8 0x42 + +# evdev 67 (0x43), QKeyCode "f9", number 0x43 +F9 0x43 + +# evdev 68 (0x44), QKeyCode "f10", number 0x44 +F10 0x44 + +# evdev 69 (0x45), QKeyCode "num_lock", number 0x45 +Num_Lock 0x45 + +# evdev 70 (0x46), QKeyCode "scroll_lock", number 0x46 +Scroll_Lock 0x46 + +# evdev 71 (0x47), QKeyCode "kp_7", number 0x47 +KP_Home 0x47 +KP_7 0x47 numlock + +# evdev 72 (0x48), QKeyCode "kp_8", number 0x48 +KP_Up 0x48 +KP_8 0x48 numlock + +# evdev 73 (0x49), QKeyCode "kp_9", number 0x49 +KP_Prior 0x49 +KP_9 0x49 numlock + +# evdev 74 (0x4a), QKeyCode "kp_subtract", number 0x4a +KP_Subtract 0x4a + +# evdev 75 (0x4b), QKeyCode "kp_4", number 0x4b +KP_Left 0x4b +KP_4 0x4b numlock + +# evdev 76 (0x4c), QKeyCode "kp_5", number 0x4c +KP_Begin 0x4c +KP_5 0x4c numlock + +# evdev 77 (0x4d), QKeyCode "kp_6", number 0x4d +KP_Right 0x4d +KP_6 0x4d numlock + +# evdev 78 (0x4e), QKeyCode "kp_add", number 0x4e +KP_Add 0x4e + +# evdev 79 (0x4f), QKeyCode "kp_1", number 0x4f +KP_End 0x4f +KP_1 0x4f numlock + +# evdev 80 (0x50), QKeyCode "kp_2", number 0x50 +KP_Down 0x50 +KP_2 0x50 numlock + +# evdev 81 (0x51), QKeyCode "kp_3", number 0x51 +KP_Next 0x51 +KP_3 0x51 numlock + +# evdev 82 (0x52), QKeyCode "kp_0", number 0x52 +KP_Insert 0x52 +KP_0 0x52 numlock + +# evdev 83 (0x53), QKeyCode "kp_decimal", number 0x53 +KP_Delete 0x53 +KP_Decimal 0x53 numlock + +# evdev 84 (0x54): no evdev -> QKeyCode mapping (xkb keysym ISO_Level3_Shift) + +# evdev 85 (0x55): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 86 (0x56), QKeyCode "less", number 0x56 +bar 0x56 +brokenbar 0x56 shift + +# evdev 87 (0x57), QKeyCode "f11", number 0x57 +F11 0x57 + +# evdev 88 (0x58), QKeyCode "f12", number 0x58 +F12 0x58 + +# evdev 89 (0x59), QKeyCode "ro", number 0x73 + +# evdev 90 (0x5a): no evdev -> QKeyCode mapping (xkb keysym Katakana) + +# evdev 91 (0x5b), QKeyCode "hiragana", number 0x77 +Hiragana 0x77 + +# evdev 92 (0x5c), QKeyCode "henkan", number 0x79 +Henkan_Mode 0x79 + +# evdev 93 (0x5d), QKeyCode "katakanahiragana", number 0x70 +Hiragana_Katakana 0x70 + +# evdev 94 (0x5e), QKeyCode "muhenkan", number 0x7b +Muhenkan 0x7b + +# evdev 95 (0x5f): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 96 (0x60), QKeyCode "kp_enter", number 0x9c +KP_Enter 0x9c + +# evdev 97 (0x61), QKeyCode "ctrl_r", number 0x9d +Control_R 0x9d + +# evdev 98 (0x62), QKeyCode "kp_divide", number 0xb5 +KP_Divide 0xb5 + +# evdev 99 (0x63), QKeyCode "sysrq", number 0x54 +Print 0x54 + +# evdev 100 (0x64), QKeyCode "alt_r", number 0xb8 +ISO_Level3_Shift 0xb8 + +# evdev 101 (0x65), QKeyCode "lf", number 0x5b +Linefeed 0x5b + +# evdev 102 (0x66), QKeyCode "home", number 0xc7 +Home 0xc7 + +# evdev 103 (0x67), QKeyCode "up", number 0xc8 +Up 0xc8 + +# evdev 104 (0x68), QKeyCode "pgup", number 0xc9 +Prior 0xc9 + +# evdev 105 (0x69), QKeyCode "left", number 0xcb +Left 0xcb + +# evdev 106 (0x6a), QKeyCode "right", number 0xcd +Right 0xcd + +# evdev 107 (0x6b), QKeyCode "end", number 0xcf +End 0xcf + +# evdev 108 (0x6c), QKeyCode "down", number 0xd0 +Down 0xd0 + +# evdev 109 (0x6d), QKeyCode "pgdn", number 0xd1 +Next 0xd1 + +# evdev 110 (0x6e), QKeyCode "insert", number 0xd2 +Insert 0xd2 + +# evdev 111 (0x6f), QKeyCode "delete", number 0xd3 +Delete 0xd3 + +# evdev 112 (0x70): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 113 (0x71), QKeyCode "audiomute", number 0xa0 +XF86AudioMute 0xa0 + +# evdev 114 (0x72), QKeyCode "volumedown", number 0xae +XF86AudioLowerVolume 0xae + +# evdev 115 (0x73), QKeyCode "volumeup", number 0xb0 +XF86AudioRaiseVolume 0xb0 + +# evdev 116 (0x74), QKeyCode "power", number 0xde +XF86PowerOff 0xde + +# evdev 117 (0x75), QKeyCode "kp_equals", number 0x59 +KP_Equal 0x59 + +# evdev 118 (0x76): no evdev -> QKeyCode mapping (xkb keysym plusminus) + +# evdev 119 (0x77), QKeyCode "pause", number 0xc6 +Pause 0xc6 + +# evdev 120 (0x78): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchA) + +# evdev 121 (0x79), QKeyCode "kp_comma", number 0x7e +KP_Decimal 0x7e + +# evdev 122 (0x7a): no evdev -> QKeyCode mapping (xkb keysym Hangul) + +# evdev 123 (0x7b): no evdev -> QKeyCode mapping (xkb keysym Hangul_Hanja) + +# evdev 124 (0x7c), QKeyCode "yen", number 0x7d + +# evdev 125 (0x7d), QKeyCode "meta_l", number 0xdb +Super_L 0xdb + +# evdev 126 (0x7e), QKeyCode "meta_r", number 0xdc +Super_R 0xdc + +# evdev 127 (0x7f), QKeyCode "compose", number 0xdd +Menu 0xdd + +# evdev 128 (0x80), QKeyCode "stop", number 0xe8 +Cancel 0xe8 + +# evdev 129 (0x81), QKeyCode "again", number 0x85 +Redo 0x85 + +# evdev 130 (0x82), QKeyCode "props", number 0x86 +SunProps 0x86 + +# evdev 131 (0x83), QKeyCode "undo", number 0x87 +Undo 0x87 + +# evdev 132 (0x84), QKeyCode "front", number 0x8c +SunFront 0x8c + +# evdev 133 (0x85), QKeyCode "copy", number 0xf8 +XF86Copy 0xf8 + +# evdev 134 (0x86), QKeyCode "open", number 0x64 +XF86Open 0x64 + +# evdev 135 (0x87), QKeyCode "paste", number 0x65 +XF86Paste 0x65 + +# evdev 136 (0x88), QKeyCode "find", number 0xc1 +Find 0xc1 + +# evdev 137 (0x89), QKeyCode "cut", number 0xbc +XF86Cut 0xbc + +# evdev 138 (0x8a), QKeyCode "help", number 0xf5 +Help 0xf5 + +# evdev 139 (0x8b), QKeyCode "menu", number 0x9e +XF86MenuKB 0x9e + +# evdev 140 (0x8c), QKeyCode "calculator", number 0xa1 +XF86Calculator 0xa1 + +# evdev 141 (0x8d): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 142 (0x8e), QKeyCode "sleep", number 0xdf +XF86Sleep 0xdf + +# evdev 143 (0x8f), QKeyCode "wake", number 0xe3 +XF86WakeUp 0xe3 + +# evdev 144 (0x90): no evdev -> QKeyCode mapping (xkb keysym XF86Explorer) + +# evdev 145 (0x91): no evdev -> QKeyCode mapping (xkb keysym XF86Send) + +# evdev 146 (0x92): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 147 (0x93): no evdev -> QKeyCode mapping (xkb keysym XF86Xfer) + +# evdev 148 (0x94): no evdev -> QKeyCode mapping (xkb keysym XF86Launch1) + +# evdev 149 (0x95): no evdev -> QKeyCode mapping (xkb keysym XF86Launch2) + +# evdev 150 (0x96): no evdev -> QKeyCode mapping (xkb keysym XF86WWW) + +# evdev 151 (0x97): no evdev -> QKeyCode mapping (xkb keysym XF86DOS) + +# evdev 152 (0x98): no evdev -> QKeyCode mapping (xkb keysym XF86ScreenSaver) + +# evdev 153 (0x99): no evdev -> QKeyCode mapping (xkb keysym XF86RotateWindows) + +# evdev 154 (0x9a): no evdev -> QKeyCode mapping (xkb keysym XF86TaskPane) + +# evdev 155 (0x9b), QKeyCode "mail", number 0xec +XF86Mail 0xec + +# evdev 156 (0x9c), QKeyCode "ac_bookmarks", number 0xe6 +XF86Favorites 0xe6 + +# evdev 157 (0x9d), QKeyCode "computer", number 0xeb +XF86MyComputer 0xeb + +# evdev 158 (0x9e), QKeyCode "ac_back", number 0xea +XF86Back 0xea + +# evdev 159 (0x9f), QKeyCode "ac_forward", number 0xe9 +XF86Forward 0xe9 + +# evdev 160 (0xa0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 161 (0xa1): no evdev -> QKeyCode mapping (xkb keysym XF86Eject) + +# evdev 162 (0xa2): no evdev -> QKeyCode mapping (xkb keysym XF86Eject) + +# evdev 163 (0xa3), QKeyCode "audionext", number 0x99 +XF86AudioNext 0x99 + +# evdev 164 (0xa4), QKeyCode "audioplay", number 0xa2 +XF86AudioPlay 0xa2 +XF86AudioPause 0xa2 shift + +# evdev 165 (0xa5), QKeyCode "audioprev", number 0x90 +XF86AudioPrev 0x90 + +# evdev 166 (0xa6), QKeyCode "audiostop", number 0xa4 +XF86AudioStop 0xa4 +XF86Eject 0xa4 shift + +# evdev 167 (0xa7): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRecord) + +# evdev 168 (0xa8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRewind) + +# evdev 169 (0xa9): no evdev -> QKeyCode mapping (xkb keysym XF86Phone) + +# evdev 170 (0xaa): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 171 (0xab): no evdev -> QKeyCode mapping (xkb keysym XF86Tools) + +# evdev 172 (0xac), QKeyCode "ac_home", number 0xb2 +XF86HomePage 0xb2 + +# evdev 173 (0xad), QKeyCode "ac_refresh", number 0xe7 +XF86Reload 0xe7 + +# evdev 174 (0xae): no evdev -> QKeyCode mapping (xkb keysym XF86Close) + +# evdev 175 (0xaf): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 176 (0xb0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 177 (0xb1): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollUp) + +# evdev 178 (0xb2): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollDown) + +# evdev 179 (0xb3): no evdev -> QKeyCode mapping (xkb keysym parenleft) + +# evdev 180 (0xb4): no evdev -> QKeyCode mapping (xkb keysym parenright) + +# evdev 181 (0xb5): no evdev -> QKeyCode mapping (xkb keysym XF86New) + +# evdev 182 (0xb6): no evdev -> QKeyCode mapping (xkb keysym Redo) + +# evdev 183 (0xb7): no evdev -> QKeyCode mapping (xkb keysym XF86Tools) + +# evdev 184 (0xb8): no evdev -> QKeyCode mapping (xkb keysym XF86Launch5) + +# evdev 185 (0xb9): no evdev -> QKeyCode mapping (xkb keysym XF86Launch6) + +# evdev 186 (0xba): no evdev -> QKeyCode mapping (xkb keysym XF86Launch7) + +# evdev 187 (0xbb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch8) + +# evdev 188 (0xbc): no evdev -> QKeyCode mapping (xkb keysym XF86Launch9) + +# evdev 189 (0xbd): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 190 (0xbe): no evdev -> QKeyCode mapping (xkb keysym XF86AudioMicMute) + +# evdev 191 (0xbf): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadToggle) + +# evdev 192 (0xc0): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOn) + +# evdev 193 (0xc1): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOff) + +# evdev 194 (0xc2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 195 (0xc3): no evdev -> QKeyCode mapping (xkb keysym Mode_switch) + +# evdev 196 (0xc4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 197 (0xc5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 198 (0xc6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 199 (0xc7): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 200 (0xc8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay) + +# evdev 201 (0xc9): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPause) + +# evdev 202 (0xca): no evdev -> QKeyCode mapping (xkb keysym XF86Launch3) + +# evdev 203 (0xcb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch4) + +# evdev 204 (0xcc): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchB) + +# evdev 205 (0xcd): no evdev -> QKeyCode mapping (xkb keysym XF86Suspend) + +# evdev 206 (0xce): no evdev -> QKeyCode mapping (xkb keysym XF86Close) + +# evdev 207 (0xcf): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay) + +# evdev 208 (0xd0): no evdev -> QKeyCode mapping (xkb keysym XF86AudioForward) + +# evdev 209 (0xd1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 210 (0xd2): no evdev -> QKeyCode mapping (xkb keysym Print) + +# evdev 211 (0xd3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 212 (0xd4): no evdev -> QKeyCode mapping (xkb keysym XF86WebCam) + +# evdev 213 (0xd5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 214 (0xd6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 215 (0xd7): no evdev -> QKeyCode mapping (xkb keysym XF86Mail) + +# evdev 216 (0xd8): no evdev -> QKeyCode mapping (xkb keysym XF86Messenger) + +# evdev 217 (0xd9): no evdev -> QKeyCode mapping (xkb keysym XF86Search) + +# evdev 218 (0xda): no evdev -> QKeyCode mapping (xkb keysym XF86Go) + +# evdev 219 (0xdb): no evdev -> QKeyCode mapping (xkb keysym XF86Finance) + +# evdev 220 (0xdc): no evdev -> QKeyCode mapping (xkb keysym XF86Game) + +# evdev 221 (0xdd): no evdev -> QKeyCode mapping (xkb keysym XF86Shop) + +# evdev 222 (0xde): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 223 (0xdf): no evdev -> QKeyCode mapping (xkb keysym Cancel) + +# evdev 224 (0xe0): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessDown) + +# evdev 225 (0xe1): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessUp) + +# evdev 226 (0xe2), QKeyCode "mediaselect", number 0xed +XF86AudioMedia 0xed + +# evdev 227 (0xe3): no evdev -> QKeyCode mapping (xkb keysym XF86Display) + +# evdev 228 (0xe4): no evdev -> QKeyCode mapping (xkb keysym XF86KbdLightOnOff) + +# evdev 229 (0xe5): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessDown) + +# evdev 230 (0xe6): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessUp) + +# evdev 231 (0xe7): no evdev -> QKeyCode mapping (xkb keysym XF86Send) + +# evdev 232 (0xe8): no evdev -> QKeyCode mapping (xkb keysym XF86Reply) + +# evdev 233 (0xe9): no evdev -> QKeyCode mapping (xkb keysym XF86MailForward) + +# evdev 234 (0xea): no evdev -> QKeyCode mapping (xkb keysym XF86Save) + +# evdev 235 (0xeb): no evdev -> QKeyCode mapping (xkb keysym XF86Documents) + +# evdev 236 (0xec): no evdev -> QKeyCode mapping (xkb keysym XF86Battery) + +# evdev 237 (0xed): no evdev -> QKeyCode mapping (xkb keysym XF86Bluetooth) + +# evdev 238 (0xee): no evdev -> QKeyCode mapping (xkb keysym XF86WLAN) + +# evdev 239 (0xef): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 240 (0xf0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 241 (0xf1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 242 (0xf2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 243 (0xf3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 244 (0xf4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 245 (0xf5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 246 (0xf6): no evdev -> QKeyCode mapping (xkb keysym Invalid) + +# evdev 247 (0xf7): no evdev -> QKeyCode mapping (xkb keysym Invalid) + +# +# quirks section start +# +# Sometimes multiple keysyms map to the same keycodes. +# The keycode -> keysym lookup finds only one of the +# keysyms. So append them here. +# + +Print 0x54 +Sys_Req 0x54 +Execute 0x54 +KP_Decimal 0x53 numlock +KP_Separator 0x53 numlock +Alt_R 0xb8 +ISO_Level3_Shift 0xb8 +Mode_switch 0xb8 + +# quirks section end diff --git a/app/src/main/assets/roms/keymaps/bepo b/app/src/main/assets/roms/keymaps/bepo new file mode 100644 index 0000000..2292cbc --- /dev/null +++ b/app/src/main/assets/roms/keymaps/bepo @@ -0,0 +1,787 @@ +# +# generated by qemu-keymap +# model : pc105 +# layout : fr +# variant : dvorak +# options : - + +# name: "French (Dvorak)" + +# modifiers +# 0: Shift +# 1: Lock +# 2: Control +# 3: Mod1 +# 4: Mod2 +# 5: Mod3 +# 6: Mod4 +# 7: Mod5 +# 8: NumLock +# 9: Alt +# 10: LevelThree +# 11: LAlt +# 12: RAlt +# 13: RControl +# 14: LControl +# 15: ScrollLock +# 16: LevelFive +# 17: AltGr +# 18: Meta +# 19: Super +# 20: Hyper + +# evdev 1 (0x1), QKeyCode "esc", number 0x1 +Escape 0x01 + +# evdev 2 (0x2), QKeyCode "1", number 0x2 +equal 0x02 +1 0x02 shift + +# evdev 3 (0x3), QKeyCode "2", number 0x3 +slash 0x03 +2 0x03 shift +plusminus 0x03 altgr + +# evdev 4 (0x4), QKeyCode "3", number 0x4 +minus 0x04 +3 0x04 shift +onequarter 0x04 altgr + +# evdev 5 (0x5), QKeyCode "4", number 0x5 +egrave 0x05 +4 0x05 shift +onehalf 0x05 altgr + +# evdev 6 (0x6), QKeyCode "5", number 0x6 +backslash 0x06 +5 0x06 shift +threequarters 0x06 altgr + +# evdev 7 (0x7), QKeyCode "6", number 0x7 +dead_circumflex 0x07 +6 0x07 shift + +# evdev 8 (0x8), QKeyCode "7", number 0x8 +parenleft 0x08 +7 0x08 shift + +# evdev 9 (0x9), QKeyCode "8", number 0x9 +ISO_Level3_Latch 0x09 +8 0x09 shift +grave 0x09 altgr + +# evdev 10 (0xa), QKeyCode "9", number 0xa +parenright 0x0a +9 0x0a shift + +# evdev 11 (0xb), QKeyCode "0", number 0xb +quotedbl 0x0b +0 0x0b shift + +# evdev 12 (0xc), QKeyCode "minus", number 0xc +bracketleft 0x0c +plus 0x0c shift + +# evdev 13 (0xd), QKeyCode "equal", number 0xd +bracketright 0x0d +percent 0x0d shift + +# evdev 14 (0xe), QKeyCode "backspace", number 0xe +BackSpace 0x0e + +# evdev 15 (0xf), QKeyCode "tab", number 0xf +Tab 0x0f +ISO_Left_Tab 0x0f shift + +# evdev 16 (0x10), QKeyCode "q", number 0x10 +colon 0x10 +question 0x10 shift +ae 0x10 altgr +AE 0x10 shift altgr + +# evdev 17 (0x11), QKeyCode "w", number 0x11 +apostrophe 0x11 +less 0x11 shift +dollar 0x11 altgr + +# evdev 18 (0x12), QKeyCode "e", number 0x12 +eacute 0x12 +greater 0x12 shift +Eacute 0x12 altgr + +# evdev 19 (0x13), QKeyCode "r", number 0x13 +g 0x13 +G 0x13 shift +EuroSign 0x13 altgr + +# evdev 20 (0x14), QKeyCode "t", number 0x14 +period 0x14 +exclam 0x14 shift +degree 0x14 altgr + +# evdev 21 (0x15), QKeyCode "y", number 0x15 +h 0x15 +H 0x15 shift + +# evdev 22 (0x16), QKeyCode "u", number 0x16 +v 0x16 +V 0x16 shift + +# evdev 23 (0x17), QKeyCode "i", number 0x17 +c 0x17 +C 0x17 shift +ccedilla 0x17 altgr +Ccedilla 0x17 shift altgr + +# evdev 24 (0x18), QKeyCode "o", number 0x18 +m 0x18 +M 0x18 shift +mu 0x18 altgr + +# evdev 25 (0x19), QKeyCode "p", number 0x19 +k 0x19 +K 0x19 shift + +# evdev 26 (0x1a), QKeyCode "bracket_left", number 0x1a +z 0x1a +Z 0x1a shift + +# evdev 27 (0x1b), QKeyCode "bracket_right", number 0x1b +dead_diaeresis 0x1b +ampersand 0x1b shift + +# evdev 28 (0x1c), QKeyCode "ret", number 0x1c +Return 0x1c + +# evdev 29 (0x1d), QKeyCode "ctrl", number 0x1d +Control_L 0x1d + +# evdev 30 (0x1e), QKeyCode "a", number 0x1e +o 0x1e +O 0x1e shift +ograve 0x1e altgr +Ograve 0x1e shift altgr + +# evdev 31 (0x1f), QKeyCode "s", number 0x1f +a 0x1f +A 0x1f shift +agrave 0x1f altgr +Agrave 0x1f shift altgr + +# evdev 32 (0x20), QKeyCode "d", number 0x20 +u 0x20 +U 0x20 shift +ugrave 0x20 altgr +Ugrave 0x20 shift altgr + +# evdev 33 (0x21), QKeyCode "f", number 0x21 +e 0x21 +E 0x21 shift +egrave 0x21 altgr +Egrave 0x21 shift altgr + +# evdev 34 (0x22), QKeyCode "g", number 0x22 +b 0x22 +B 0x22 shift + +# evdev 35 (0x23), QKeyCode "h", number 0x23 +f 0x23 +F 0x23 shift + +# evdev 36 (0x24), QKeyCode "j", number 0x24 +s 0x24 +S 0x24 shift +guillemotleft 0x24 altgr + +# evdev 37 (0x25), QKeyCode "k", number 0x25 +t 0x25 +T 0x25 shift + +# evdev 38 (0x26), QKeyCode "l", number 0x26 +n 0x26 +N 0x26 shift +guillemotright 0x26 altgr + +# evdev 39 (0x27), QKeyCode "semicolon", number 0x27 +d 0x27 +D 0x27 shift + +# evdev 40 (0x28), QKeyCode "apostrophe", number 0x28 +w 0x28 +W 0x28 shift + +# evdev 41 (0x29), QKeyCode "grave_accent", number 0x29 +underscore 0x29 +asterisk 0x29 shift + +# evdev 42 (0x2a), QKeyCode "shift", number 0x2a +Shift_L 0x2a + +# evdev 43 (0x2b), QKeyCode "backslash", number 0x2b +asciitilde 0x2b +numbersign 0x2b shift + +# evdev 44 (0x2c), QKeyCode "z", number 0x2c +semicolon 0x2c +bar 0x2c shift +oe 0x2c altgr +OE 0x2c shift altgr + +# evdev 45 (0x2d), QKeyCode "x", number 0x2d +q 0x2d +Q 0x2d shift +braceleft 0x2d altgr + +# evdev 46 (0x2e), QKeyCode "c", number 0x2e +comma 0x2e +at 0x2e shift +braceright 0x2e altgr + +# evdev 47 (0x2f), QKeyCode "v", number 0x2f +i 0x2f +I 0x2f shift +igrave 0x2f altgr +Igrave 0x2f shift altgr + +# evdev 48 (0x30), QKeyCode "b", number 0x30 +y 0x30 +Y 0x30 shift +sterling 0x30 altgr + +# evdev 49 (0x31), QKeyCode "n", number 0x31 +x 0x31 +X 0x31 shift + +# evdev 50 (0x32), QKeyCode "m", number 0x32 +r 0x32 +R 0x32 shift +masculine 0x32 altgr + +# evdev 51 (0x33), QKeyCode "comma", number 0x33 +l 0x33 +L 0x33 shift + +# evdev 52 (0x34), QKeyCode "dot", number 0x34 +p 0x34 +P 0x34 shift +section 0x34 altgr + +# evdev 53 (0x35), QKeyCode "slash", number 0x35 +j 0x35 +J 0x35 shift + +# evdev 54 (0x36), QKeyCode "shift_r", number 0x36 +Shift_R 0x36 + +# evdev 55 (0x37), QKeyCode "kp_multiply", number 0x37 +KP_Multiply 0x37 + +# evdev 56 (0x38), QKeyCode "alt", number 0x38 +Alt_L 0x38 +Meta_L 0x38 shift + +# evdev 57 (0x39), QKeyCode "spc", number 0x39 +space 0x39 +nobreakspace 0x39 altgr + +# evdev 58 (0x3a), QKeyCode "caps_lock", number 0x3a +Caps_Lock 0x3a + +# evdev 59 (0x3b), QKeyCode "f1", number 0x3b +F1 0x3b + +# evdev 60 (0x3c), QKeyCode "f2", number 0x3c +F2 0x3c + +# evdev 61 (0x3d), QKeyCode "f3", number 0x3d +F3 0x3d + +# evdev 62 (0x3e), QKeyCode "f4", number 0x3e +F4 0x3e + +# evdev 63 (0x3f), QKeyCode "f5", number 0x3f +F5 0x3f + +# evdev 64 (0x40), QKeyCode "f6", number 0x40 +F6 0x40 + +# evdev 65 (0x41), QKeyCode "f7", number 0x41 +F7 0x41 + +# evdev 66 (0x42), QKeyCode "f8", number 0x42 +F8 0x42 + +# evdev 67 (0x43), QKeyCode "f9", number 0x43 +F9 0x43 + +# evdev 68 (0x44), QKeyCode "f10", number 0x44 +F10 0x44 + +# evdev 69 (0x45), QKeyCode "num_lock", number 0x45 +Num_Lock 0x45 + +# evdev 70 (0x46), QKeyCode "scroll_lock", number 0x46 +Scroll_Lock 0x46 + +# evdev 71 (0x47), QKeyCode "kp_7", number 0x47 +KP_Home 0x47 +KP_7 0x47 numlock + +# evdev 72 (0x48), QKeyCode "kp_8", number 0x48 +KP_Up 0x48 +KP_8 0x48 numlock + +# evdev 73 (0x49), QKeyCode "kp_9", number 0x49 +KP_Prior 0x49 +KP_9 0x49 numlock + +# evdev 74 (0x4a), QKeyCode "kp_subtract", number 0x4a +KP_Subtract 0x4a + +# evdev 75 (0x4b), QKeyCode "kp_4", number 0x4b +KP_Left 0x4b +KP_4 0x4b numlock + +# evdev 76 (0x4c), QKeyCode "kp_5", number 0x4c +KP_Begin 0x4c +KP_5 0x4c numlock + +# evdev 77 (0x4d), QKeyCode "kp_6", number 0x4d +KP_Right 0x4d +KP_6 0x4d numlock + +# evdev 78 (0x4e), QKeyCode "kp_add", number 0x4e +KP_Add 0x4e + +# evdev 79 (0x4f), QKeyCode "kp_1", number 0x4f +KP_End 0x4f +KP_1 0x4f numlock + +# evdev 80 (0x50), QKeyCode "kp_2", number 0x50 +KP_Down 0x50 +KP_2 0x50 numlock + +# evdev 81 (0x51), QKeyCode "kp_3", number 0x51 +KP_Next 0x51 +KP_3 0x51 numlock + +# evdev 82 (0x52), QKeyCode "kp_0", number 0x52 +KP_Insert 0x52 +KP_0 0x52 numlock + +# evdev 83 (0x53), QKeyCode "kp_decimal", number 0x53 +KP_Delete 0x53 +KP_Decimal 0x53 numlock + +# evdev 84 (0x54): no evdev -> QKeyCode mapping (xkb keysym ISO_Level3_Shift) + +# evdev 85 (0x55): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 86 (0x56), QKeyCode "less", number 0x56 +agrave 0x56 +ccedilla 0x56 shift +Agrave 0x56 altgr +Ccedilla 0x56 shift altgr + +# evdev 87 (0x57), QKeyCode "f11", number 0x57 +F11 0x57 + +# evdev 88 (0x58), QKeyCode "f12", number 0x58 +F12 0x58 + +# evdev 89 (0x59), QKeyCode "ro", number 0x73 + +# evdev 90 (0x5a): no evdev -> QKeyCode mapping (xkb keysym Katakana) + +# evdev 91 (0x5b), QKeyCode "hiragana", number 0x77 +Hiragana 0x77 + +# evdev 92 (0x5c), QKeyCode "henkan", number 0x79 +Henkan_Mode 0x79 + +# evdev 93 (0x5d), QKeyCode "katakanahiragana", number 0x70 +Hiragana_Katakana 0x70 + +# evdev 94 (0x5e), QKeyCode "muhenkan", number 0x7b +Muhenkan 0x7b + +# evdev 95 (0x5f): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 96 (0x60), QKeyCode "kp_enter", number 0x9c +KP_Enter 0x9c + +# evdev 97 (0x61), QKeyCode "ctrl_r", number 0x9d +Control_R 0x9d + +# evdev 98 (0x62), QKeyCode "kp_divide", number 0xb5 +KP_Divide 0xb5 + +# evdev 99 (0x63), QKeyCode "sysrq", number 0x54 +Print 0x54 + +# evdev 100 (0x64), QKeyCode "alt_r", number 0xb8 +Alt_R 0xb8 +Meta_R 0xb8 shift + +# evdev 101 (0x65), QKeyCode "lf", number 0x5b +Linefeed 0x5b + +# evdev 102 (0x66), QKeyCode "home", number 0xc7 +Home 0xc7 + +# evdev 103 (0x67), QKeyCode "up", number 0xc8 +Up 0xc8 + +# evdev 104 (0x68), QKeyCode "pgup", number 0xc9 +Prior 0xc9 + +# evdev 105 (0x69), QKeyCode "left", number 0xcb +Left 0xcb + +# evdev 106 (0x6a), QKeyCode "right", number 0xcd +Right 0xcd + +# evdev 107 (0x6b), QKeyCode "end", number 0xcf +End 0xcf + +# evdev 108 (0x6c), QKeyCode "down", number 0xd0 +Down 0xd0 + +# evdev 109 (0x6d), QKeyCode "pgdn", number 0xd1 +Next 0xd1 + +# evdev 110 (0x6e), QKeyCode "insert", number 0xd2 +Insert 0xd2 + +# evdev 111 (0x6f), QKeyCode "delete", number 0xd3 +Delete 0xd3 + +# evdev 112 (0x70): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 113 (0x71), QKeyCode "audiomute", number 0xa0 +XF86AudioMute 0xa0 + +# evdev 114 (0x72), QKeyCode "volumedown", number 0xae +XF86AudioLowerVolume 0xae + +# evdev 115 (0x73), QKeyCode "volumeup", number 0xb0 +XF86AudioRaiseVolume 0xb0 + +# evdev 116 (0x74), QKeyCode "power", number 0xde +XF86PowerOff 0xde + +# evdev 117 (0x75), QKeyCode "kp_equals", number 0x59 +KP_Equal 0x59 + +# evdev 118 (0x76): no evdev -> QKeyCode mapping (xkb keysym plusminus) + +# evdev 119 (0x77), QKeyCode "pause", number 0xc6 +Pause 0xc6 + +# evdev 120 (0x78): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchA) + +# evdev 121 (0x79), QKeyCode "kp_comma", number 0x7e +KP_Decimal 0x7e + +# evdev 122 (0x7a): no evdev -> QKeyCode mapping (xkb keysym Hangul) + +# evdev 123 (0x7b): no evdev -> QKeyCode mapping (xkb keysym Hangul_Hanja) + +# evdev 124 (0x7c), QKeyCode "yen", number 0x7d + +# evdev 125 (0x7d), QKeyCode "meta_l", number 0xdb +Super_L 0xdb + +# evdev 126 (0x7e), QKeyCode "meta_r", number 0xdc +Super_R 0xdc + +# evdev 127 (0x7f), QKeyCode "compose", number 0xdd +Menu 0xdd + +# evdev 128 (0x80), QKeyCode "stop", number 0xe8 +Cancel 0xe8 + +# evdev 129 (0x81), QKeyCode "again", number 0x85 +Redo 0x85 + +# evdev 130 (0x82), QKeyCode "props", number 0x86 +SunProps 0x86 + +# evdev 131 (0x83), QKeyCode "undo", number 0x87 +Undo 0x87 + +# evdev 132 (0x84), QKeyCode "front", number 0x8c +SunFront 0x8c + +# evdev 133 (0x85), QKeyCode "copy", number 0xf8 +XF86Copy 0xf8 + +# evdev 134 (0x86), QKeyCode "open", number 0x64 +XF86Open 0x64 + +# evdev 135 (0x87), QKeyCode "paste", number 0x65 +XF86Paste 0x65 + +# evdev 136 (0x88), QKeyCode "find", number 0xc1 +Find 0xc1 + +# evdev 137 (0x89), QKeyCode "cut", number 0xbc +XF86Cut 0xbc + +# evdev 138 (0x8a), QKeyCode "help", number 0xf5 +Help 0xf5 + +# evdev 139 (0x8b), QKeyCode "menu", number 0x9e +XF86MenuKB 0x9e + +# evdev 140 (0x8c), QKeyCode "calculator", number 0xa1 +XF86Calculator 0xa1 + +# evdev 141 (0x8d): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 142 (0x8e), QKeyCode "sleep", number 0xdf +XF86Sleep 0xdf + +# evdev 143 (0x8f), QKeyCode "wake", number 0xe3 +XF86WakeUp 0xe3 + +# evdev 144 (0x90): no evdev -> QKeyCode mapping (xkb keysym XF86Explorer) + +# evdev 145 (0x91): no evdev -> QKeyCode mapping (xkb keysym XF86Send) + +# evdev 146 (0x92): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 147 (0x93): no evdev -> QKeyCode mapping (xkb keysym XF86Xfer) + +# evdev 148 (0x94): no evdev -> QKeyCode mapping (xkb keysym XF86Launch1) + +# evdev 149 (0x95): no evdev -> QKeyCode mapping (xkb keysym XF86Launch2) + +# evdev 150 (0x96): no evdev -> QKeyCode mapping (xkb keysym XF86WWW) + +# evdev 151 (0x97): no evdev -> QKeyCode mapping (xkb keysym XF86DOS) + +# evdev 152 (0x98): no evdev -> QKeyCode mapping (xkb keysym XF86ScreenSaver) + +# evdev 153 (0x99): no evdev -> QKeyCode mapping (xkb keysym XF86RotateWindows) + +# evdev 154 (0x9a): no evdev -> QKeyCode mapping (xkb keysym XF86TaskPane) + +# evdev 155 (0x9b), QKeyCode "mail", number 0xec +XF86Mail 0xec + +# evdev 156 (0x9c), QKeyCode "ac_bookmarks", number 0xe6 +XF86Favorites 0xe6 + +# evdev 157 (0x9d), QKeyCode "computer", number 0xeb +XF86MyComputer 0xeb + +# evdev 158 (0x9e), QKeyCode "ac_back", number 0xea +XF86Back 0xea + +# evdev 159 (0x9f), QKeyCode "ac_forward", number 0xe9 +XF86Forward 0xe9 + +# evdev 160 (0xa0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 161 (0xa1): no evdev -> QKeyCode mapping (xkb keysym XF86Eject) + +# evdev 162 (0xa2): no evdev -> QKeyCode mapping (xkb keysym XF86Eject) + +# evdev 163 (0xa3), QKeyCode "audionext", number 0x99 +XF86AudioNext 0x99 + +# evdev 164 (0xa4), QKeyCode "audioplay", number 0xa2 +XF86AudioPlay 0xa2 +XF86AudioPause 0xa2 shift + +# evdev 165 (0xa5), QKeyCode "audioprev", number 0x90 +XF86AudioPrev 0x90 + +# evdev 166 (0xa6), QKeyCode "audiostop", number 0xa4 +XF86AudioStop 0xa4 +XF86Eject 0xa4 shift + +# evdev 167 (0xa7): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRecord) + +# evdev 168 (0xa8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRewind) + +# evdev 169 (0xa9): no evdev -> QKeyCode mapping (xkb keysym XF86Phone) + +# evdev 170 (0xaa): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 171 (0xab): no evdev -> QKeyCode mapping (xkb keysym XF86Tools) + +# evdev 172 (0xac), QKeyCode "ac_home", number 0xb2 +XF86HomePage 0xb2 + +# evdev 173 (0xad), QKeyCode "ac_refresh", number 0xe7 +XF86Reload 0xe7 + +# evdev 174 (0xae): no evdev -> QKeyCode mapping (xkb keysym XF86Close) + +# evdev 175 (0xaf): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 176 (0xb0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 177 (0xb1): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollUp) + +# evdev 178 (0xb2): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollDown) + +# evdev 179 (0xb3): no evdev -> QKeyCode mapping (xkb keysym parenleft) + +# evdev 180 (0xb4): no evdev -> QKeyCode mapping (xkb keysym parenright) + +# evdev 181 (0xb5): no evdev -> QKeyCode mapping (xkb keysym XF86New) + +# evdev 182 (0xb6): no evdev -> QKeyCode mapping (xkb keysym Redo) + +# evdev 183 (0xb7): no evdev -> QKeyCode mapping (xkb keysym XF86Tools) + +# evdev 184 (0xb8): no evdev -> QKeyCode mapping (xkb keysym XF86Launch5) + +# evdev 185 (0xb9): no evdev -> QKeyCode mapping (xkb keysym XF86Launch6) + +# evdev 186 (0xba): no evdev -> QKeyCode mapping (xkb keysym XF86Launch7) + +# evdev 187 (0xbb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch8) + +# evdev 188 (0xbc): no evdev -> QKeyCode mapping (xkb keysym XF86Launch9) + +# evdev 189 (0xbd): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 190 (0xbe): no evdev -> QKeyCode mapping (xkb keysym XF86AudioMicMute) + +# evdev 191 (0xbf): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadToggle) + +# evdev 192 (0xc0): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOn) + +# evdev 193 (0xc1): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOff) + +# evdev 194 (0xc2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 195 (0xc3): no evdev -> QKeyCode mapping (xkb keysym Mode_switch) + +# evdev 196 (0xc4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 197 (0xc5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 198 (0xc6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 199 (0xc7): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 200 (0xc8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay) + +# evdev 201 (0xc9): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPause) + +# evdev 202 (0xca): no evdev -> QKeyCode mapping (xkb keysym XF86Launch3) + +# evdev 203 (0xcb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch4) + +# evdev 204 (0xcc): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchB) + +# evdev 205 (0xcd): no evdev -> QKeyCode mapping (xkb keysym XF86Suspend) + +# evdev 206 (0xce): no evdev -> QKeyCode mapping (xkb keysym XF86Close) + +# evdev 207 (0xcf): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay) + +# evdev 208 (0xd0): no evdev -> QKeyCode mapping (xkb keysym XF86AudioForward) + +# evdev 209 (0xd1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 210 (0xd2): no evdev -> QKeyCode mapping (xkb keysym Print) + +# evdev 211 (0xd3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 212 (0xd4): no evdev -> QKeyCode mapping (xkb keysym XF86WebCam) + +# evdev 213 (0xd5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 214 (0xd6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 215 (0xd7): no evdev -> QKeyCode mapping (xkb keysym XF86Mail) + +# evdev 216 (0xd8): no evdev -> QKeyCode mapping (xkb keysym XF86Messenger) + +# evdev 217 (0xd9): no evdev -> QKeyCode mapping (xkb keysym XF86Search) + +# evdev 218 (0xda): no evdev -> QKeyCode mapping (xkb keysym XF86Go) + +# evdev 219 (0xdb): no evdev -> QKeyCode mapping (xkb keysym XF86Finance) + +# evdev 220 (0xdc): no evdev -> QKeyCode mapping (xkb keysym XF86Game) + +# evdev 221 (0xdd): no evdev -> QKeyCode mapping (xkb keysym XF86Shop) + +# evdev 222 (0xde): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 223 (0xdf): no evdev -> QKeyCode mapping (xkb keysym Cancel) + +# evdev 224 (0xe0): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessDown) + +# evdev 225 (0xe1): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessUp) + +# evdev 226 (0xe2), QKeyCode "mediaselect", number 0xed +XF86AudioMedia 0xed + +# evdev 227 (0xe3): no evdev -> QKeyCode mapping (xkb keysym XF86Display) + +# evdev 228 (0xe4): no evdev -> QKeyCode mapping (xkb keysym XF86KbdLightOnOff) + +# evdev 229 (0xe5): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessDown) + +# evdev 230 (0xe6): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessUp) + +# evdev 231 (0xe7): no evdev -> QKeyCode mapping (xkb keysym XF86Send) + +# evdev 232 (0xe8): no evdev -> QKeyCode mapping (xkb keysym XF86Reply) + +# evdev 233 (0xe9): no evdev -> QKeyCode mapping (xkb keysym XF86MailForward) + +# evdev 234 (0xea): no evdev -> QKeyCode mapping (xkb keysym XF86Save) + +# evdev 235 (0xeb): no evdev -> QKeyCode mapping (xkb keysym XF86Documents) + +# evdev 236 (0xec): no evdev -> QKeyCode mapping (xkb keysym XF86Battery) + +# evdev 237 (0xed): no evdev -> QKeyCode mapping (xkb keysym XF86Bluetooth) + +# evdev 238 (0xee): no evdev -> QKeyCode mapping (xkb keysym XF86WLAN) + +# evdev 239 (0xef): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 240 (0xf0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 241 (0xf1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 242 (0xf2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 243 (0xf3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 244 (0xf4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 245 (0xf5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 246 (0xf6): no evdev -> QKeyCode mapping (xkb keysym Invalid) + +# evdev 247 (0xf7): no evdev -> QKeyCode mapping (xkb keysym Invalid) + +# +# quirks section start +# +# Sometimes multiple keysyms map to the same keycodes. +# The keycode -> keysym lookup finds only one of the +# keysyms. So append them here. +# + +Print 0x54 +Sys_Req 0x54 +Execute 0x54 +KP_Decimal 0x53 numlock +KP_Separator 0x53 numlock +Alt_R 0xb8 +ISO_Level3_Shift 0xb8 +Mode_switch 0xb8 + +# quirks section end diff --git a/app/src/main/assets/roms/keymaps/cz b/app/src/main/assets/roms/keymaps/cz new file mode 100644 index 0000000..29cf2b0 --- /dev/null +++ b/app/src/main/assets/roms/keymaps/cz @@ -0,0 +1,843 @@ +# +# generated by qemu-keymap +# model : pc105 +# layout : cz +# variant : - +# options : - + +# name: "Czech" + +# modifiers +# 0: Shift +# 1: Lock +# 2: Control +# 3: Mod1 +# 4: Mod2 +# 5: Mod3 +# 6: Mod4 +# 7: Mod5 +# 8: NumLock +# 9: Alt +# 10: LevelThree +# 11: LAlt +# 12: RAlt +# 13: RControl +# 14: LControl +# 15: ScrollLock +# 16: LevelFive +# 17: AltGr +# 18: Meta +# 19: Super +# 20: Hyper + +# evdev 1 (0x1), QKeyCode "esc", number 0x1 +Escape 0x01 + +# evdev 2 (0x2), QKeyCode "1", number 0x2 +plus 0x02 +1 0x02 shift +exclam 0x02 altgr +dead_tilde 0x02 shift altgr + +# evdev 3 (0x3), QKeyCode "2", number 0x3 +ecaron 0x03 +2 0x03 shift +at 0x03 altgr +dead_caron 0x03 shift altgr + +# evdev 4 (0x4), QKeyCode "3", number 0x4 +scaron 0x04 +3 0x04 shift +numbersign 0x04 altgr +dead_circumflex 0x04 shift altgr + +# evdev 5 (0x5), QKeyCode "4", number 0x5 +ccaron 0x05 +4 0x05 shift +dollar 0x05 altgr +dead_breve 0x05 shift altgr + +# evdev 6 (0x6), QKeyCode "5", number 0x6 +rcaron 0x06 +5 0x06 shift +percent 0x06 altgr +dead_abovering 0x06 shift altgr + +# evdev 7 (0x7), QKeyCode "6", number 0x7 +zcaron 0x07 +6 0x07 shift +asciicircum 0x07 altgr +dead_ogonek 0x07 shift altgr + +# evdev 8 (0x8), QKeyCode "7", number 0x8 +yacute 0x08 +7 0x08 shift +ampersand 0x08 altgr +dead_grave 0x08 shift altgr + +# evdev 9 (0x9), QKeyCode "8", number 0x9 +aacute 0x09 +8 0x09 shift +asterisk 0x09 altgr +dead_abovedot 0x09 shift altgr + +# evdev 10 (0xa), QKeyCode "9", number 0xa +iacute 0x0a +9 0x0a shift +braceleft 0x0a altgr +dead_acute 0x0a shift altgr + +# evdev 11 (0xb), QKeyCode "0", number 0xb +eacute 0x0b +0 0x0b shift +braceright 0x0b altgr +dead_doubleacute 0x0b shift altgr + +# evdev 12 (0xc), QKeyCode "minus", number 0xc +equal 0x0c +percent 0x0c shift +backslash 0x0c altgr +dead_diaeresis 0x0c shift altgr + +# evdev 13 (0xd), QKeyCode "equal", number 0xd +dead_acute 0x0d +dead_caron 0x0d shift +dead_macron 0x0d altgr +dead_cedilla 0x0d shift altgr + +# evdev 14 (0xe), QKeyCode "backspace", number 0xe +BackSpace 0x0e + +# evdev 15 (0xf), QKeyCode "tab", number 0xf +Tab 0x0f +ISO_Left_Tab 0x0f shift + +# evdev 16 (0x10), QKeyCode "q", number 0x10 +q 0x10 +Q 0x10 shift +backslash 0x10 altgr +Greek_OMEGA 0x10 shift altgr + +# evdev 17 (0x11), QKeyCode "w", number 0x11 +w 0x11 +W 0x11 shift +bar 0x11 altgr +Lstroke 0x11 shift altgr + +# evdev 18 (0x12), QKeyCode "e", number 0x12 +e 0x12 +E 0x12 shift +EuroSign 0x12 altgr + +# evdev 19 (0x13), QKeyCode "r", number 0x13 +r 0x13 +R 0x13 shift +paragraph 0x13 altgr +registered 0x13 shift altgr + +# evdev 20 (0x14), QKeyCode "t", number 0x14 +t 0x14 +T 0x14 shift +tslash 0x14 altgr +Tslash 0x14 shift altgr + +# evdev 21 (0x15), QKeyCode "y", number 0x15 +z 0x15 +Z 0x15 shift +leftarrow 0x15 altgr +yen 0x15 shift altgr + +# evdev 22 (0x16), QKeyCode "u", number 0x16 +u 0x16 +U 0x16 shift +downarrow 0x16 altgr +uparrow 0x16 shift altgr + +# evdev 23 (0x17), QKeyCode "i", number 0x17 +i 0x17 +I 0x17 shift +rightarrow 0x17 altgr +idotless 0x17 shift altgr + +# evdev 24 (0x18), QKeyCode "o", number 0x18 +o 0x18 +O 0x18 shift +oslash 0x18 altgr +Oslash 0x18 shift altgr + +# evdev 25 (0x19), QKeyCode "p", number 0x19 +p 0x19 +P 0x19 shift +thorn 0x19 altgr +THORN 0x19 shift altgr + +# evdev 26 (0x1a), QKeyCode "bracket_left", number 0x1a +uacute 0x1a +slash 0x1a shift +bracketleft 0x1a altgr +division 0x1a shift altgr + +# evdev 27 (0x1b), QKeyCode "bracket_right", number 0x1b +parenright 0x1b +parenleft 0x1b shift +bracketright 0x1b altgr +multiply 0x1b shift altgr + +# evdev 28 (0x1c), QKeyCode "ret", number 0x1c +Return 0x1c + +# evdev 29 (0x1d), QKeyCode "ctrl", number 0x1d +Control_L 0x1d + +# evdev 30 (0x1e), QKeyCode "a", number 0x1e +a 0x1e +A 0x1e shift +asciitilde 0x1e altgr +AE 0x1e shift altgr + +# evdev 31 (0x1f), QKeyCode "s", number 0x1f +s 0x1f +S 0x1f shift +dstroke 0x1f altgr +section 0x1f shift altgr + +# evdev 32 (0x20), QKeyCode "d", number 0x20 +d 0x20 +D 0x20 shift +Dstroke 0x20 altgr +ETH 0x20 shift altgr + +# evdev 33 (0x21), QKeyCode "f", number 0x21 +f 0x21 +F 0x21 shift +bracketleft 0x21 altgr +ordfeminine 0x21 shift altgr + +# evdev 34 (0x22), QKeyCode "g", number 0x22 +g 0x22 +G 0x22 shift +bracketright 0x22 altgr +ENG 0x22 shift altgr + +# evdev 35 (0x23), QKeyCode "h", number 0x23 +h 0x23 +H 0x23 shift +grave 0x23 altgr +Hstroke 0x23 shift altgr + +# evdev 36 (0x24), QKeyCode "j", number 0x24 +j 0x24 +J 0x24 shift +apostrophe 0x24 altgr +dead_horn 0x24 shift altgr + +# evdev 37 (0x25), QKeyCode "k", number 0x25 +k 0x25 +K 0x25 shift +lstroke 0x25 altgr +ampersand 0x25 shift altgr + +# evdev 38 (0x26), QKeyCode "l", number 0x26 +l 0x26 +L 0x26 shift +Lstroke 0x26 altgr + +# evdev 39 (0x27), QKeyCode "semicolon", number 0x27 +uring 0x27 +quotedbl 0x27 shift +dollar 0x27 altgr +dead_doubleacute 0x27 shift altgr + +# evdev 40 (0x28), QKeyCode "apostrophe", number 0x28 +section 0x28 +exclam 0x28 shift +apostrophe 0x28 altgr +ssharp 0x28 shift altgr + +# evdev 41 (0x29), QKeyCode "grave_accent", number 0x29 +semicolon 0x29 +dead_abovering 0x29 shift +grave 0x29 altgr +asciitilde 0x29 shift altgr + +# evdev 42 (0x2a), QKeyCode "shift", number 0x2a +Shift_L 0x2a + +# evdev 43 (0x2b), QKeyCode "backslash", number 0x2b +dead_diaeresis 0x2b +apostrophe 0x2b shift +backslash 0x2b altgr +bar 0x2b shift altgr + +# evdev 44 (0x2c), QKeyCode "z", number 0x2c +y 0x2c +Y 0x2c shift +degree 0x2c altgr +less 0x2c shift altgr + +# evdev 45 (0x2d), QKeyCode "x", number 0x2d +x 0x2d +X 0x2d shift +numbersign 0x2d altgr +greater 0x2d shift altgr + +# evdev 46 (0x2e), QKeyCode "c", number 0x2e +c 0x2e +C 0x2e shift +ampersand 0x2e altgr +copyright 0x2e shift altgr + +# evdev 47 (0x2f), QKeyCode "v", number 0x2f +v 0x2f +V 0x2f shift +at 0x2f altgr +leftsinglequotemark 0x2f shift altgr + +# evdev 48 (0x30), QKeyCode "b", number 0x30 +b 0x30 +B 0x30 shift +braceleft 0x30 altgr +rightsinglequotemark 0x30 shift altgr + +# evdev 49 (0x31), QKeyCode "n", number 0x31 +n 0x31 +N 0x31 shift +braceright 0x31 altgr + +# evdev 50 (0x32), QKeyCode "m", number 0x32 +m 0x32 +M 0x32 shift +asciicircum 0x32 altgr +masculine 0x32 shift altgr + +# evdev 51 (0x33), QKeyCode "comma", number 0x33 +comma 0x33 +question 0x33 shift +less 0x33 altgr +multiply 0x33 shift altgr + +# evdev 52 (0x34), QKeyCode "dot", number 0x34 +period 0x34 +colon 0x34 shift +greater 0x34 altgr +division 0x34 shift altgr + +# evdev 53 (0x35), QKeyCode "slash", number 0x35 +minus 0x35 +underscore 0x35 shift +asterisk 0x35 altgr +dead_abovedot 0x35 shift altgr + +# evdev 54 (0x36), QKeyCode "shift_r", number 0x36 +Shift_R 0x36 + +# evdev 55 (0x37), QKeyCode "kp_multiply", number 0x37 +KP_Multiply 0x37 + +# evdev 56 (0x38), QKeyCode "alt", number 0x38 +Alt_L 0x38 +Meta_L 0x38 shift + +# evdev 57 (0x39), QKeyCode "spc", number 0x39 +space 0x39 + +# evdev 58 (0x3a), QKeyCode "caps_lock", number 0x3a +Caps_Lock 0x3a + +# evdev 59 (0x3b), QKeyCode "f1", number 0x3b +F1 0x3b + +# evdev 60 (0x3c), QKeyCode "f2", number 0x3c +F2 0x3c + +# evdev 61 (0x3d), QKeyCode "f3", number 0x3d +F3 0x3d + +# evdev 62 (0x3e), QKeyCode "f4", number 0x3e +F4 0x3e + +# evdev 63 (0x3f), QKeyCode "f5", number 0x3f +F5 0x3f + +# evdev 64 (0x40), QKeyCode "f6", number 0x40 +F6 0x40 + +# evdev 65 (0x41), QKeyCode "f7", number 0x41 +F7 0x41 + +# evdev 66 (0x42), QKeyCode "f8", number 0x42 +F8 0x42 + +# evdev 67 (0x43), QKeyCode "f9", number 0x43 +F9 0x43 + +# evdev 68 (0x44), QKeyCode "f10", number 0x44 +F10 0x44 + +# evdev 69 (0x45), QKeyCode "num_lock", number 0x45 +Num_Lock 0x45 + +# evdev 70 (0x46), QKeyCode "scroll_lock", number 0x46 +Scroll_Lock 0x46 + +# evdev 71 (0x47), QKeyCode "kp_7", number 0x47 +KP_Home 0x47 +KP_7 0x47 numlock + +# evdev 72 (0x48), QKeyCode "kp_8", number 0x48 +KP_Up 0x48 +KP_8 0x48 numlock + +# evdev 73 (0x49), QKeyCode "kp_9", number 0x49 +KP_Prior 0x49 +KP_9 0x49 numlock + +# evdev 74 (0x4a), QKeyCode "kp_subtract", number 0x4a +KP_Subtract 0x4a + +# evdev 75 (0x4b), QKeyCode "kp_4", number 0x4b +KP_Left 0x4b +KP_4 0x4b numlock + +# evdev 76 (0x4c), QKeyCode "kp_5", number 0x4c +KP_Begin 0x4c +KP_5 0x4c numlock + +# evdev 77 (0x4d), QKeyCode "kp_6", number 0x4d +KP_Right 0x4d +KP_6 0x4d numlock + +# evdev 78 (0x4e), QKeyCode "kp_add", number 0x4e +KP_Add 0x4e + +# evdev 79 (0x4f), QKeyCode "kp_1", number 0x4f +KP_End 0x4f +KP_1 0x4f numlock + +# evdev 80 (0x50), QKeyCode "kp_2", number 0x50 +KP_Down 0x50 +KP_2 0x50 numlock + +# evdev 81 (0x51), QKeyCode "kp_3", number 0x51 +KP_Next 0x51 +KP_3 0x51 numlock + +# evdev 82 (0x52), QKeyCode "kp_0", number 0x52 +KP_Insert 0x52 +KP_0 0x52 numlock + +# evdev 83 (0x53), QKeyCode "kp_decimal", number 0x53 +KP_Delete 0x53 +KP_Decimal 0x53 numlock + +# evdev 84 (0x54): no evdev -> QKeyCode mapping (xkb keysym ISO_Level3_Shift) + +# evdev 85 (0x55): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 86 (0x56), QKeyCode "less", number 0x56 +backslash 0x56 +bar 0x56 shift +slash 0x56 altgr +brokenbar 0x56 shift altgr + +# evdev 87 (0x57), QKeyCode "f11", number 0x57 +F11 0x57 + +# evdev 88 (0x58), QKeyCode "f12", number 0x58 +F12 0x58 + +# evdev 89 (0x59), QKeyCode "ro", number 0x73 + +# evdev 90 (0x5a): no evdev -> QKeyCode mapping (xkb keysym Katakana) + +# evdev 91 (0x5b), QKeyCode "hiragana", number 0x77 +Hiragana 0x77 + +# evdev 92 (0x5c), QKeyCode "henkan", number 0x79 +Henkan_Mode 0x79 + +# evdev 93 (0x5d), QKeyCode "katakanahiragana", number 0x70 +Hiragana_Katakana 0x70 + +# evdev 94 (0x5e), QKeyCode "muhenkan", number 0x7b +Muhenkan 0x7b + +# evdev 95 (0x5f): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 96 (0x60), QKeyCode "kp_enter", number 0x9c +KP_Enter 0x9c + +# evdev 97 (0x61), QKeyCode "ctrl_r", number 0x9d +Control_R 0x9d + +# evdev 98 (0x62), QKeyCode "kp_divide", number 0xb5 +KP_Divide 0xb5 + +# evdev 99 (0x63), QKeyCode "sysrq", number 0x54 +Print 0x54 + +# evdev 100 (0x64), QKeyCode "alt_r", number 0xb8 +ISO_Level3_Shift 0xb8 + +# evdev 101 (0x65), QKeyCode "lf", number 0x5b +Linefeed 0x5b + +# evdev 102 (0x66), QKeyCode "home", number 0xc7 +Home 0xc7 + +# evdev 103 (0x67), QKeyCode "up", number 0xc8 +Up 0xc8 + +# evdev 104 (0x68), QKeyCode "pgup", number 0xc9 +Prior 0xc9 + +# evdev 105 (0x69), QKeyCode "left", number 0xcb +Left 0xcb + +# evdev 106 (0x6a), QKeyCode "right", number 0xcd +Right 0xcd + +# evdev 107 (0x6b), QKeyCode "end", number 0xcf +End 0xcf + +# evdev 108 (0x6c), QKeyCode "down", number 0xd0 +Down 0xd0 + +# evdev 109 (0x6d), QKeyCode "pgdn", number 0xd1 +Next 0xd1 + +# evdev 110 (0x6e), QKeyCode "insert", number 0xd2 +Insert 0xd2 + +# evdev 111 (0x6f), QKeyCode "delete", number 0xd3 +Delete 0xd3 + +# evdev 112 (0x70): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 113 (0x71), QKeyCode "audiomute", number 0xa0 +XF86AudioMute 0xa0 + +# evdev 114 (0x72), QKeyCode "volumedown", number 0xae +XF86AudioLowerVolume 0xae + +# evdev 115 (0x73), QKeyCode "volumeup", number 0xb0 +XF86AudioRaiseVolume 0xb0 + +# evdev 116 (0x74), QKeyCode "power", number 0xde +XF86PowerOff 0xde + +# evdev 117 (0x75), QKeyCode "kp_equals", number 0x59 +KP_Equal 0x59 + +# evdev 118 (0x76): no evdev -> QKeyCode mapping (xkb keysym plusminus) + +# evdev 119 (0x77), QKeyCode "pause", number 0xc6 +Pause 0xc6 + +# evdev 120 (0x78): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchA) + +# evdev 121 (0x79), QKeyCode "kp_comma", number 0x7e +KP_Decimal 0x7e + +# evdev 122 (0x7a): no evdev -> QKeyCode mapping (xkb keysym Hangul) + +# evdev 123 (0x7b): no evdev -> QKeyCode mapping (xkb keysym Hangul_Hanja) + +# evdev 124 (0x7c), QKeyCode "yen", number 0x7d + +# evdev 125 (0x7d), QKeyCode "meta_l", number 0xdb +Super_L 0xdb + +# evdev 126 (0x7e), QKeyCode "meta_r", number 0xdc +Super_R 0xdc + +# evdev 127 (0x7f), QKeyCode "compose", number 0xdd +Menu 0xdd + +# evdev 128 (0x80), QKeyCode "stop", number 0xe8 +Cancel 0xe8 + +# evdev 129 (0x81), QKeyCode "again", number 0x85 +Redo 0x85 + +# evdev 130 (0x82), QKeyCode "props", number 0x86 +SunProps 0x86 + +# evdev 131 (0x83), QKeyCode "undo", number 0x87 +Undo 0x87 + +# evdev 132 (0x84), QKeyCode "front", number 0x8c +SunFront 0x8c + +# evdev 133 (0x85), QKeyCode "copy", number 0xf8 +XF86Copy 0xf8 + +# evdev 134 (0x86), QKeyCode "open", number 0x64 +XF86Open 0x64 + +# evdev 135 (0x87), QKeyCode "paste", number 0x65 +XF86Paste 0x65 + +# evdev 136 (0x88), QKeyCode "find", number 0xc1 +Find 0xc1 + +# evdev 137 (0x89), QKeyCode "cut", number 0xbc +XF86Cut 0xbc + +# evdev 138 (0x8a), QKeyCode "help", number 0xf5 +Help 0xf5 + +# evdev 139 (0x8b), QKeyCode "menu", number 0x9e +XF86MenuKB 0x9e + +# evdev 140 (0x8c), QKeyCode "calculator", number 0xa1 +XF86Calculator 0xa1 + +# evdev 141 (0x8d): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 142 (0x8e), QKeyCode "sleep", number 0xdf +XF86Sleep 0xdf + +# evdev 143 (0x8f), QKeyCode "wake", number 0xe3 +XF86WakeUp 0xe3 + +# evdev 144 (0x90): no evdev -> QKeyCode mapping (xkb keysym XF86Explorer) + +# evdev 145 (0x91): no evdev -> QKeyCode mapping (xkb keysym XF86Send) + +# evdev 146 (0x92): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 147 (0x93): no evdev -> QKeyCode mapping (xkb keysym XF86Xfer) + +# evdev 148 (0x94): no evdev -> QKeyCode mapping (xkb keysym XF86Launch1) + +# evdev 149 (0x95): no evdev -> QKeyCode mapping (xkb keysym XF86Launch2) + +# evdev 150 (0x96): no evdev -> QKeyCode mapping (xkb keysym XF86WWW) + +# evdev 151 (0x97): no evdev -> QKeyCode mapping (xkb keysym XF86DOS) + +# evdev 152 (0x98): no evdev -> QKeyCode mapping (xkb keysym XF86ScreenSaver) + +# evdev 153 (0x99): no evdev -> QKeyCode mapping (xkb keysym XF86RotateWindows) + +# evdev 154 (0x9a): no evdev -> QKeyCode mapping (xkb keysym XF86TaskPane) + +# evdev 155 (0x9b), QKeyCode "mail", number 0xec +XF86Mail 0xec + +# evdev 156 (0x9c), QKeyCode "ac_bookmarks", number 0xe6 +XF86Favorites 0xe6 + +# evdev 157 (0x9d), QKeyCode "computer", number 0xeb +XF86MyComputer 0xeb + +# evdev 158 (0x9e), QKeyCode "ac_back", number 0xea +XF86Back 0xea + +# evdev 159 (0x9f), QKeyCode "ac_forward", number 0xe9 +XF86Forward 0xe9 + +# evdev 160 (0xa0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 161 (0xa1): no evdev -> QKeyCode mapping (xkb keysym XF86Eject) + +# evdev 162 (0xa2): no evdev -> QKeyCode mapping (xkb keysym XF86Eject) + +# evdev 163 (0xa3), QKeyCode "audionext", number 0x99 +XF86AudioNext 0x99 + +# evdev 164 (0xa4), QKeyCode "audioplay", number 0xa2 +XF86AudioPlay 0xa2 +XF86AudioPause 0xa2 shift + +# evdev 165 (0xa5), QKeyCode "audioprev", number 0x90 +XF86AudioPrev 0x90 + +# evdev 166 (0xa6), QKeyCode "audiostop", number 0xa4 +XF86AudioStop 0xa4 +XF86Eject 0xa4 shift + +# evdev 167 (0xa7): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRecord) + +# evdev 168 (0xa8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRewind) + +# evdev 169 (0xa9): no evdev -> QKeyCode mapping (xkb keysym XF86Phone) + +# evdev 170 (0xaa): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 171 (0xab): no evdev -> QKeyCode mapping (xkb keysym XF86Tools) + +# evdev 172 (0xac), QKeyCode "ac_home", number 0xb2 +XF86HomePage 0xb2 + +# evdev 173 (0xad), QKeyCode "ac_refresh", number 0xe7 +XF86Reload 0xe7 + +# evdev 174 (0xae): no evdev -> QKeyCode mapping (xkb keysym XF86Close) + +# evdev 175 (0xaf): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 176 (0xb0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 177 (0xb1): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollUp) + +# evdev 178 (0xb2): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollDown) + +# evdev 179 (0xb3): no evdev -> QKeyCode mapping (xkb keysym parenleft) + +# evdev 180 (0xb4): no evdev -> QKeyCode mapping (xkb keysym parenright) + +# evdev 181 (0xb5): no evdev -> QKeyCode mapping (xkb keysym XF86New) + +# evdev 182 (0xb6): no evdev -> QKeyCode mapping (xkb keysym Redo) + +# evdev 183 (0xb7): no evdev -> QKeyCode mapping (xkb keysym XF86Tools) + +# evdev 184 (0xb8): no evdev -> QKeyCode mapping (xkb keysym XF86Launch5) + +# evdev 185 (0xb9): no evdev -> QKeyCode mapping (xkb keysym XF86Launch6) + +# evdev 186 (0xba): no evdev -> QKeyCode mapping (xkb keysym XF86Launch7) + +# evdev 187 (0xbb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch8) + +# evdev 188 (0xbc): no evdev -> QKeyCode mapping (xkb keysym XF86Launch9) + +# evdev 189 (0xbd): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 190 (0xbe): no evdev -> QKeyCode mapping (xkb keysym XF86AudioMicMute) + +# evdev 191 (0xbf): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadToggle) + +# evdev 192 (0xc0): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOn) + +# evdev 193 (0xc1): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOff) + +# evdev 194 (0xc2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 195 (0xc3): no evdev -> QKeyCode mapping (xkb keysym Mode_switch) + +# evdev 196 (0xc4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 197 (0xc5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 198 (0xc6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 199 (0xc7): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 200 (0xc8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay) + +# evdev 201 (0xc9): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPause) + +# evdev 202 (0xca): no evdev -> QKeyCode mapping (xkb keysym XF86Launch3) + +# evdev 203 (0xcb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch4) + +# evdev 204 (0xcc): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchB) + +# evdev 205 (0xcd): no evdev -> QKeyCode mapping (xkb keysym XF86Suspend) + +# evdev 206 (0xce): no evdev -> QKeyCode mapping (xkb keysym XF86Close) + +# evdev 207 (0xcf): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay) + +# evdev 208 (0xd0): no evdev -> QKeyCode mapping (xkb keysym XF86AudioForward) + +# evdev 209 (0xd1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 210 (0xd2): no evdev -> QKeyCode mapping (xkb keysym Print) + +# evdev 211 (0xd3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 212 (0xd4): no evdev -> QKeyCode mapping (xkb keysym XF86WebCam) + +# evdev 213 (0xd5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 214 (0xd6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 215 (0xd7): no evdev -> QKeyCode mapping (xkb keysym XF86Mail) + +# evdev 216 (0xd8): no evdev -> QKeyCode mapping (xkb keysym XF86Messenger) + +# evdev 217 (0xd9): no evdev -> QKeyCode mapping (xkb keysym XF86Search) + +# evdev 218 (0xda): no evdev -> QKeyCode mapping (xkb keysym XF86Go) + +# evdev 219 (0xdb): no evdev -> QKeyCode mapping (xkb keysym XF86Finance) + +# evdev 220 (0xdc): no evdev -> QKeyCode mapping (xkb keysym XF86Game) + +# evdev 221 (0xdd): no evdev -> QKeyCode mapping (xkb keysym XF86Shop) + +# evdev 222 (0xde): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 223 (0xdf): no evdev -> QKeyCode mapping (xkb keysym Cancel) + +# evdev 224 (0xe0): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessDown) + +# evdev 225 (0xe1): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessUp) + +# evdev 226 (0xe2), QKeyCode "mediaselect", number 0xed +XF86AudioMedia 0xed + +# evdev 227 (0xe3): no evdev -> QKeyCode mapping (xkb keysym XF86Display) + +# evdev 228 (0xe4): no evdev -> QKeyCode mapping (xkb keysym XF86KbdLightOnOff) + +# evdev 229 (0xe5): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessDown) + +# evdev 230 (0xe6): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessUp) + +# evdev 231 (0xe7): no evdev -> QKeyCode mapping (xkb keysym XF86Send) + +# evdev 232 (0xe8): no evdev -> QKeyCode mapping (xkb keysym XF86Reply) + +# evdev 233 (0xe9): no evdev -> QKeyCode mapping (xkb keysym XF86MailForward) + +# evdev 234 (0xea): no evdev -> QKeyCode mapping (xkb keysym XF86Save) + +# evdev 235 (0xeb): no evdev -> QKeyCode mapping (xkb keysym XF86Documents) + +# evdev 236 (0xec): no evdev -> QKeyCode mapping (xkb keysym XF86Battery) + +# evdev 237 (0xed): no evdev -> QKeyCode mapping (xkb keysym XF86Bluetooth) + +# evdev 238 (0xee): no evdev -> QKeyCode mapping (xkb keysym XF86WLAN) + +# evdev 239 (0xef): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 240 (0xf0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 241 (0xf1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 242 (0xf2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 243 (0xf3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 244 (0xf4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 245 (0xf5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 246 (0xf6): no evdev -> QKeyCode mapping (xkb keysym Invalid) + +# evdev 247 (0xf7): no evdev -> QKeyCode mapping (xkb keysym Invalid) + +# +# quirks section start +# +# Sometimes multiple keysyms map to the same keycodes. +# The keycode -> keysym lookup finds only one of the +# keysyms. So append them here. +# + +Print 0x54 +Sys_Req 0x54 +Execute 0x54 +KP_Decimal 0x53 numlock +KP_Separator 0x53 numlock +Alt_R 0xb8 +ISO_Level3_Shift 0xb8 +Mode_switch 0xb8 + +# quirks section end diff --git a/app/src/main/assets/roms/keymaps/da b/app/src/main/assets/roms/keymaps/da new file mode 100644 index 0000000..547d8c7 --- /dev/null +++ b/app/src/main/assets/roms/keymaps/da @@ -0,0 +1,842 @@ +# +# generated by qemu-keymap +# model : pc105 +# layout : dk +# variant : - +# options : - + +# name: "Danish" + +# modifiers +# 0: Shift +# 1: Lock +# 2: Control +# 3: Mod1 +# 4: Mod2 +# 5: Mod3 +# 6: Mod4 +# 7: Mod5 +# 8: NumLock +# 9: Alt +# 10: LevelThree +# 11: LAlt +# 12: RAlt +# 13: RControl +# 14: LControl +# 15: ScrollLock +# 16: LevelFive +# 17: AltGr +# 18: Meta +# 19: Super +# 20: Hyper + +# evdev 1 (0x1), QKeyCode "esc", number 0x1 +Escape 0x01 + +# evdev 2 (0x2), QKeyCode "1", number 0x2 +1 0x02 +exclam 0x02 shift +exclamdown 0x02 altgr +onesuperior 0x02 shift altgr + +# evdev 3 (0x3), QKeyCode "2", number 0x3 +2 0x03 +quotedbl 0x03 shift +at 0x03 altgr +twosuperior 0x03 shift altgr + +# evdev 4 (0x4), QKeyCode "3", number 0x4 +3 0x04 +numbersign 0x04 shift +sterling 0x04 altgr +threesuperior 0x04 shift altgr + +# evdev 5 (0x5), QKeyCode "4", number 0x5 +4 0x05 +currency 0x05 shift +dollar 0x05 altgr +onequarter 0x05 shift altgr + +# evdev 6 (0x6), QKeyCode "5", number 0x6 +5 0x06 +percent 0x06 shift +onehalf 0x06 altgr +cent 0x06 shift altgr + +# evdev 7 (0x7), QKeyCode "6", number 0x7 +6 0x07 +ampersand 0x07 shift +yen 0x07 altgr +fiveeighths 0x07 shift altgr + +# evdev 8 (0x8), QKeyCode "7", number 0x8 +7 0x08 +slash 0x08 shift +braceleft 0x08 altgr +division 0x08 shift altgr + +# evdev 9 (0x9), QKeyCode "8", number 0x9 +8 0x09 +parenleft 0x09 shift +bracketleft 0x09 altgr +guillemotleft 0x09 shift altgr + +# evdev 10 (0xa), QKeyCode "9", number 0xa +9 0x0a +parenright 0x0a shift +bracketright 0x0a altgr +guillemotright 0x0a shift altgr + +# evdev 11 (0xb), QKeyCode "0", number 0xb +0 0x0b +equal 0x0b shift +braceright 0x0b altgr +degree 0x0b shift altgr + +# evdev 12 (0xc), QKeyCode "minus", number 0xc +plus 0x0c +question 0x0c shift +plusminus 0x0c altgr +questiondown 0x0c shift altgr + +# evdev 13 (0xd), QKeyCode "equal", number 0xd +dead_acute 0x0d +dead_grave 0x0d shift +bar 0x0d altgr +brokenbar 0x0d shift altgr + +# evdev 14 (0xe), QKeyCode "backspace", number 0xe +BackSpace 0x0e + +# evdev 15 (0xf), QKeyCode "tab", number 0xf +Tab 0x0f +ISO_Left_Tab 0x0f shift + +# evdev 16 (0x10), QKeyCode "q", number 0x10 +q 0x10 +Q 0x10 shift +at 0x10 altgr +Greek_OMEGA 0x10 shift altgr + +# evdev 17 (0x11), QKeyCode "w", number 0x11 +w 0x11 +W 0x11 shift +lstroke 0x11 altgr +Lstroke 0x11 shift altgr + +# evdev 18 (0x12), QKeyCode "e", number 0x12 +e 0x12 +E 0x12 shift +EuroSign 0x12 altgr +cent 0x12 shift altgr + +# evdev 19 (0x13), QKeyCode "r", number 0x13 +r 0x13 +R 0x13 shift +registered 0x13 altgr + +# evdev 20 (0x14), QKeyCode "t", number 0x14 +t 0x14 +T 0x14 shift +thorn 0x14 altgr +THORN 0x14 shift altgr + +# evdev 21 (0x15), QKeyCode "y", number 0x15 +y 0x15 +Y 0x15 shift +leftarrow 0x15 altgr +yen 0x15 shift altgr + +# evdev 22 (0x16), QKeyCode "u", number 0x16 +u 0x16 +U 0x16 shift +downarrow 0x16 altgr +uparrow 0x16 shift altgr + +# evdev 23 (0x17), QKeyCode "i", number 0x17 +i 0x17 +I 0x17 shift +rightarrow 0x17 altgr +idotless 0x17 shift altgr + +# evdev 24 (0x18), QKeyCode "o", number 0x18 +o 0x18 +O 0x18 shift +oe 0x18 altgr +OE 0x18 shift altgr + +# evdev 25 (0x19), QKeyCode "p", number 0x19 +p 0x19 +P 0x19 shift +thorn 0x19 altgr +THORN 0x19 shift altgr + +# evdev 26 (0x1a), QKeyCode "bracket_left", number 0x1a +aring 0x1a +Aring 0x1a shift +dead_diaeresis 0x1a altgr +dead_abovering 0x1a shift altgr + +# evdev 27 (0x1b), QKeyCode "bracket_right", number 0x1b +dead_diaeresis 0x1b +dead_circumflex 0x1b shift +dead_tilde 0x1b altgr +dead_caron 0x1b shift altgr + +# evdev 28 (0x1c), QKeyCode "ret", number 0x1c +Return 0x1c + +# evdev 29 (0x1d), QKeyCode "ctrl", number 0x1d +Control_L 0x1d + +# evdev 30 (0x1e), QKeyCode "a", number 0x1e +a 0x1e +A 0x1e shift +ordfeminine 0x1e altgr +masculine 0x1e shift altgr + +# evdev 31 (0x1f), QKeyCode "s", number 0x1f +s 0x1f +S 0x1f shift +ssharp 0x1f altgr +section 0x1f shift altgr + +# evdev 32 (0x20), QKeyCode "d", number 0x20 +d 0x20 +D 0x20 shift +eth 0x20 altgr +ETH 0x20 shift altgr + +# evdev 33 (0x21), QKeyCode "f", number 0x21 +f 0x21 +F 0x21 shift +dstroke 0x21 altgr +ordfeminine 0x21 shift altgr + +# evdev 34 (0x22), QKeyCode "g", number 0x22 +g 0x22 +G 0x22 shift +eng 0x22 altgr +ENG 0x22 shift altgr + +# evdev 35 (0x23), QKeyCode "h", number 0x23 +h 0x23 +H 0x23 shift +hstroke 0x23 altgr +Hstroke 0x23 shift altgr + +# evdev 36 (0x24), QKeyCode "j", number 0x24 +j 0x24 +J 0x24 shift +dead_hook 0x24 altgr +dead_horn 0x24 shift altgr + +# evdev 37 (0x25), QKeyCode "k", number 0x25 +k 0x25 +K 0x25 shift +kra 0x25 altgr +ampersand 0x25 shift altgr + +# evdev 38 (0x26), QKeyCode "l", number 0x26 +l 0x26 +L 0x26 shift +lstroke 0x26 altgr +Lstroke 0x26 shift altgr + +# evdev 39 (0x27), QKeyCode "semicolon", number 0x27 +ae 0x27 +AE 0x27 shift +dead_acute 0x27 altgr +dead_doubleacute 0x27 shift altgr + +# evdev 40 (0x28), QKeyCode "apostrophe", number 0x28 +oslash 0x28 +Oslash 0x28 shift +dead_circumflex 0x28 altgr +dead_caron 0x28 shift altgr + +# evdev 41 (0x29), QKeyCode "grave_accent", number 0x29 +onehalf 0x29 +section 0x29 shift +threequarters 0x29 altgr +paragraph 0x29 shift altgr + +# evdev 42 (0x2a), QKeyCode "shift", number 0x2a +Shift_L 0x2a + +# evdev 43 (0x2b), QKeyCode "backslash", number 0x2b +apostrophe 0x2b +asterisk 0x2b shift +dead_doubleacute 0x2b altgr +multiply 0x2b shift altgr + +# evdev 44 (0x2c), QKeyCode "z", number 0x2c +z 0x2c +Z 0x2c shift +guillemotleft 0x2c altgr +less 0x2c shift altgr + +# evdev 45 (0x2d), QKeyCode "x", number 0x2d +x 0x2d +X 0x2d shift +guillemotright 0x2d altgr +greater 0x2d shift altgr + +# evdev 46 (0x2e), QKeyCode "c", number 0x2e +c 0x2e +C 0x2e shift +copyright 0x2e altgr + +# evdev 47 (0x2f), QKeyCode "v", number 0x2f +v 0x2f +V 0x2f shift +leftdoublequotemark 0x2f altgr +leftsinglequotemark 0x2f shift altgr + +# evdev 48 (0x30), QKeyCode "b", number 0x30 +b 0x30 +B 0x30 shift +rightdoublequotemark 0x30 altgr +rightsinglequotemark 0x30 shift altgr + +# evdev 49 (0x31), QKeyCode "n", number 0x31 +n 0x31 +N 0x31 shift + +# evdev 50 (0x32), QKeyCode "m", number 0x32 +m 0x32 +M 0x32 shift +mu 0x32 altgr +masculine 0x32 shift altgr + +# evdev 51 (0x33), QKeyCode "comma", number 0x33 +comma 0x33 +semicolon 0x33 shift +dead_cedilla 0x33 altgr +dead_ogonek 0x33 shift altgr + +# evdev 52 (0x34), QKeyCode "dot", number 0x34 +period 0x34 +colon 0x34 shift +periodcentered 0x34 altgr +dead_abovedot 0x34 shift altgr + +# evdev 53 (0x35), QKeyCode "slash", number 0x35 +minus 0x35 +underscore 0x35 shift +dead_belowdot 0x35 altgr +dead_abovedot 0x35 shift altgr + +# evdev 54 (0x36), QKeyCode "shift_r", number 0x36 +Shift_R 0x36 + +# evdev 55 (0x37), QKeyCode "kp_multiply", number 0x37 +KP_Multiply 0x37 + +# evdev 56 (0x38), QKeyCode "alt", number 0x38 +Alt_L 0x38 +Meta_L 0x38 shift + +# evdev 57 (0x39), QKeyCode "spc", number 0x39 +space 0x39 + +# evdev 58 (0x3a), QKeyCode "caps_lock", number 0x3a +Caps_Lock 0x3a + +# evdev 59 (0x3b), QKeyCode "f1", number 0x3b +F1 0x3b + +# evdev 60 (0x3c), QKeyCode "f2", number 0x3c +F2 0x3c + +# evdev 61 (0x3d), QKeyCode "f3", number 0x3d +F3 0x3d + +# evdev 62 (0x3e), QKeyCode "f4", number 0x3e +F4 0x3e + +# evdev 63 (0x3f), QKeyCode "f5", number 0x3f +F5 0x3f + +# evdev 64 (0x40), QKeyCode "f6", number 0x40 +F6 0x40 + +# evdev 65 (0x41), QKeyCode "f7", number 0x41 +F7 0x41 + +# evdev 66 (0x42), QKeyCode "f8", number 0x42 +F8 0x42 + +# evdev 67 (0x43), QKeyCode "f9", number 0x43 +F9 0x43 + +# evdev 68 (0x44), QKeyCode "f10", number 0x44 +F10 0x44 + +# evdev 69 (0x45), QKeyCode "num_lock", number 0x45 +Num_Lock 0x45 + +# evdev 70 (0x46), QKeyCode "scroll_lock", number 0x46 +Scroll_Lock 0x46 + +# evdev 71 (0x47), QKeyCode "kp_7", number 0x47 +KP_Home 0x47 +KP_7 0x47 numlock + +# evdev 72 (0x48), QKeyCode "kp_8", number 0x48 +KP_Up 0x48 +KP_8 0x48 numlock + +# evdev 73 (0x49), QKeyCode "kp_9", number 0x49 +KP_Prior 0x49 +KP_9 0x49 numlock + +# evdev 74 (0x4a), QKeyCode "kp_subtract", number 0x4a +KP_Subtract 0x4a + +# evdev 75 (0x4b), QKeyCode "kp_4", number 0x4b +KP_Left 0x4b +KP_4 0x4b numlock + +# evdev 76 (0x4c), QKeyCode "kp_5", number 0x4c +KP_Begin 0x4c +KP_5 0x4c numlock + +# evdev 77 (0x4d), QKeyCode "kp_6", number 0x4d +KP_Right 0x4d +KP_6 0x4d numlock + +# evdev 78 (0x4e), QKeyCode "kp_add", number 0x4e +KP_Add 0x4e + +# evdev 79 (0x4f), QKeyCode "kp_1", number 0x4f +KP_End 0x4f +KP_1 0x4f numlock + +# evdev 80 (0x50), QKeyCode "kp_2", number 0x50 +KP_Down 0x50 +KP_2 0x50 numlock + +# evdev 81 (0x51), QKeyCode "kp_3", number 0x51 +KP_Next 0x51 +KP_3 0x51 numlock + +# evdev 82 (0x52), QKeyCode "kp_0", number 0x52 +KP_Insert 0x52 +KP_0 0x52 numlock + +# evdev 83 (0x53), QKeyCode "kp_decimal", number 0x53 +KP_Delete 0x53 +KP_Separator 0x53 numlock + +# evdev 84 (0x54): no evdev -> QKeyCode mapping (xkb keysym ISO_Level3_Shift) + +# evdev 85 (0x55): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 86 (0x56), QKeyCode "less", number 0x56 +less 0x56 +greater 0x56 shift +backslash 0x56 altgr +notsign 0x56 shift altgr + +# evdev 87 (0x57), QKeyCode "f11", number 0x57 +F11 0x57 + +# evdev 88 (0x58), QKeyCode "f12", number 0x58 +F12 0x58 + +# evdev 89 (0x59), QKeyCode "ro", number 0x73 + +# evdev 90 (0x5a): no evdev -> QKeyCode mapping (xkb keysym Katakana) + +# evdev 91 (0x5b), QKeyCode "hiragana", number 0x77 +Hiragana 0x77 + +# evdev 92 (0x5c), QKeyCode "henkan", number 0x79 +Henkan_Mode 0x79 + +# evdev 93 (0x5d), QKeyCode "katakanahiragana", number 0x70 +Hiragana_Katakana 0x70 + +# evdev 94 (0x5e), QKeyCode "muhenkan", number 0x7b +Muhenkan 0x7b + +# evdev 95 (0x5f): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 96 (0x60), QKeyCode "kp_enter", number 0x9c +KP_Enter 0x9c + +# evdev 97 (0x61), QKeyCode "ctrl_r", number 0x9d +Control_R 0x9d + +# evdev 98 (0x62), QKeyCode "kp_divide", number 0xb5 +KP_Divide 0xb5 + +# evdev 99 (0x63), QKeyCode "sysrq", number 0x54 +Print 0x54 + +# evdev 100 (0x64), QKeyCode "alt_r", number 0xb8 +ISO_Level3_Shift 0xb8 + +# evdev 101 (0x65), QKeyCode "lf", number 0x5b +Linefeed 0x5b + +# evdev 102 (0x66), QKeyCode "home", number 0xc7 +Home 0xc7 + +# evdev 103 (0x67), QKeyCode "up", number 0xc8 +Up 0xc8 + +# evdev 104 (0x68), QKeyCode "pgup", number 0xc9 +Prior 0xc9 + +# evdev 105 (0x69), QKeyCode "left", number 0xcb +Left 0xcb + +# evdev 106 (0x6a), QKeyCode "right", number 0xcd +Right 0xcd + +# evdev 107 (0x6b), QKeyCode "end", number 0xcf +End 0xcf + +# evdev 108 (0x6c), QKeyCode "down", number 0xd0 +Down 0xd0 + +# evdev 109 (0x6d), QKeyCode "pgdn", number 0xd1 +Next 0xd1 + +# evdev 110 (0x6e), QKeyCode "insert", number 0xd2 +Insert 0xd2 + +# evdev 111 (0x6f), QKeyCode "delete", number 0xd3 +Delete 0xd3 + +# evdev 112 (0x70): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 113 (0x71), QKeyCode "audiomute", number 0xa0 +XF86AudioMute 0xa0 + +# evdev 114 (0x72), QKeyCode "volumedown", number 0xae +XF86AudioLowerVolume 0xae + +# evdev 115 (0x73), QKeyCode "volumeup", number 0xb0 +XF86AudioRaiseVolume 0xb0 + +# evdev 116 (0x74), QKeyCode "power", number 0xde +XF86PowerOff 0xde + +# evdev 117 (0x75), QKeyCode "kp_equals", number 0x59 +KP_Equal 0x59 + +# evdev 118 (0x76): no evdev -> QKeyCode mapping (xkb keysym plusminus) + +# evdev 119 (0x77), QKeyCode "pause", number 0xc6 +Pause 0xc6 + +# evdev 120 (0x78): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchA) + +# evdev 121 (0x79), QKeyCode "kp_comma", number 0x7e +KP_Decimal 0x7e + +# evdev 122 (0x7a): no evdev -> QKeyCode mapping (xkb keysym Hangul) + +# evdev 123 (0x7b): no evdev -> QKeyCode mapping (xkb keysym Hangul_Hanja) + +# evdev 124 (0x7c), QKeyCode "yen", number 0x7d + +# evdev 125 (0x7d), QKeyCode "meta_l", number 0xdb +Super_L 0xdb + +# evdev 126 (0x7e), QKeyCode "meta_r", number 0xdc +Super_R 0xdc + +# evdev 127 (0x7f), QKeyCode "compose", number 0xdd +Menu 0xdd + +# evdev 128 (0x80), QKeyCode "stop", number 0xe8 +Cancel 0xe8 + +# evdev 129 (0x81), QKeyCode "again", number 0x85 +Redo 0x85 + +# evdev 130 (0x82), QKeyCode "props", number 0x86 +SunProps 0x86 + +# evdev 131 (0x83), QKeyCode "undo", number 0x87 +Undo 0x87 + +# evdev 132 (0x84), QKeyCode "front", number 0x8c +SunFront 0x8c + +# evdev 133 (0x85), QKeyCode "copy", number 0xf8 +XF86Copy 0xf8 + +# evdev 134 (0x86), QKeyCode "open", number 0x64 +XF86Open 0x64 + +# evdev 135 (0x87), QKeyCode "paste", number 0x65 +XF86Paste 0x65 + +# evdev 136 (0x88), QKeyCode "find", number 0xc1 +Find 0xc1 + +# evdev 137 (0x89), QKeyCode "cut", number 0xbc +XF86Cut 0xbc + +# evdev 138 (0x8a), QKeyCode "help", number 0xf5 +Help 0xf5 + +# evdev 139 (0x8b), QKeyCode "menu", number 0x9e +XF86MenuKB 0x9e + +# evdev 140 (0x8c), QKeyCode "calculator", number 0xa1 +XF86Calculator 0xa1 + +# evdev 141 (0x8d): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 142 (0x8e), QKeyCode "sleep", number 0xdf +XF86Sleep 0xdf + +# evdev 143 (0x8f), QKeyCode "wake", number 0xe3 +XF86WakeUp 0xe3 + +# evdev 144 (0x90): no evdev -> QKeyCode mapping (xkb keysym XF86Explorer) + +# evdev 145 (0x91): no evdev -> QKeyCode mapping (xkb keysym XF86Send) + +# evdev 146 (0x92): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 147 (0x93): no evdev -> QKeyCode mapping (xkb keysym XF86Xfer) + +# evdev 148 (0x94): no evdev -> QKeyCode mapping (xkb keysym XF86Launch1) + +# evdev 149 (0x95): no evdev -> QKeyCode mapping (xkb keysym XF86Launch2) + +# evdev 150 (0x96): no evdev -> QKeyCode mapping (xkb keysym XF86WWW) + +# evdev 151 (0x97): no evdev -> QKeyCode mapping (xkb keysym XF86DOS) + +# evdev 152 (0x98): no evdev -> QKeyCode mapping (xkb keysym XF86ScreenSaver) + +# evdev 153 (0x99): no evdev -> QKeyCode mapping (xkb keysym XF86RotateWindows) + +# evdev 154 (0x9a): no evdev -> QKeyCode mapping (xkb keysym XF86TaskPane) + +# evdev 155 (0x9b), QKeyCode "mail", number 0xec +XF86Mail 0xec + +# evdev 156 (0x9c), QKeyCode "ac_bookmarks", number 0xe6 +XF86Favorites 0xe6 + +# evdev 157 (0x9d), QKeyCode "computer", number 0xeb +XF86MyComputer 0xeb + +# evdev 158 (0x9e), QKeyCode "ac_back", number 0xea +XF86Back 0xea + +# evdev 159 (0x9f), QKeyCode "ac_forward", number 0xe9 +XF86Forward 0xe9 + +# evdev 160 (0xa0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 161 (0xa1): no evdev -> QKeyCode mapping (xkb keysym XF86Eject) + +# evdev 162 (0xa2): no evdev -> QKeyCode mapping (xkb keysym XF86Eject) + +# evdev 163 (0xa3), QKeyCode "audionext", number 0x99 +XF86AudioNext 0x99 + +# evdev 164 (0xa4), QKeyCode "audioplay", number 0xa2 +XF86AudioPlay 0xa2 +XF86AudioPause 0xa2 shift + +# evdev 165 (0xa5), QKeyCode "audioprev", number 0x90 +XF86AudioPrev 0x90 + +# evdev 166 (0xa6), QKeyCode "audiostop", number 0xa4 +XF86AudioStop 0xa4 +XF86Eject 0xa4 shift + +# evdev 167 (0xa7): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRecord) + +# evdev 168 (0xa8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRewind) + +# evdev 169 (0xa9): no evdev -> QKeyCode mapping (xkb keysym XF86Phone) + +# evdev 170 (0xaa): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 171 (0xab): no evdev -> QKeyCode mapping (xkb keysym XF86Tools) + +# evdev 172 (0xac), QKeyCode "ac_home", number 0xb2 +XF86HomePage 0xb2 + +# evdev 173 (0xad), QKeyCode "ac_refresh", number 0xe7 +XF86Reload 0xe7 + +# evdev 174 (0xae): no evdev -> QKeyCode mapping (xkb keysym XF86Close) + +# evdev 175 (0xaf): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 176 (0xb0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 177 (0xb1): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollUp) + +# evdev 178 (0xb2): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollDown) + +# evdev 179 (0xb3): no evdev -> QKeyCode mapping (xkb keysym parenleft) + +# evdev 180 (0xb4): no evdev -> QKeyCode mapping (xkb keysym parenright) + +# evdev 181 (0xb5): no evdev -> QKeyCode mapping (xkb keysym XF86New) + +# evdev 182 (0xb6): no evdev -> QKeyCode mapping (xkb keysym Redo) + +# evdev 183 (0xb7): no evdev -> QKeyCode mapping (xkb keysym XF86Tools) + +# evdev 184 (0xb8): no evdev -> QKeyCode mapping (xkb keysym XF86Launch5) + +# evdev 185 (0xb9): no evdev -> QKeyCode mapping (xkb keysym XF86Launch6) + +# evdev 186 (0xba): no evdev -> QKeyCode mapping (xkb keysym XF86Launch7) + +# evdev 187 (0xbb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch8) + +# evdev 188 (0xbc): no evdev -> QKeyCode mapping (xkb keysym XF86Launch9) + +# evdev 189 (0xbd): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 190 (0xbe): no evdev -> QKeyCode mapping (xkb keysym XF86AudioMicMute) + +# evdev 191 (0xbf): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadToggle) + +# evdev 192 (0xc0): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOn) + +# evdev 193 (0xc1): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOff) + +# evdev 194 (0xc2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 195 (0xc3): no evdev -> QKeyCode mapping (xkb keysym Mode_switch) + +# evdev 196 (0xc4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 197 (0xc5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 198 (0xc6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 199 (0xc7): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 200 (0xc8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay) + +# evdev 201 (0xc9): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPause) + +# evdev 202 (0xca): no evdev -> QKeyCode mapping (xkb keysym XF86Launch3) + +# evdev 203 (0xcb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch4) + +# evdev 204 (0xcc): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchB) + +# evdev 205 (0xcd): no evdev -> QKeyCode mapping (xkb keysym XF86Suspend) + +# evdev 206 (0xce): no evdev -> QKeyCode mapping (xkb keysym XF86Close) + +# evdev 207 (0xcf): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay) + +# evdev 208 (0xd0): no evdev -> QKeyCode mapping (xkb keysym XF86AudioForward) + +# evdev 209 (0xd1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 210 (0xd2): no evdev -> QKeyCode mapping (xkb keysym Print) + +# evdev 211 (0xd3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 212 (0xd4): no evdev -> QKeyCode mapping (xkb keysym XF86WebCam) + +# evdev 213 (0xd5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 214 (0xd6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 215 (0xd7): no evdev -> QKeyCode mapping (xkb keysym XF86Mail) + +# evdev 216 (0xd8): no evdev -> QKeyCode mapping (xkb keysym XF86Messenger) + +# evdev 217 (0xd9): no evdev -> QKeyCode mapping (xkb keysym XF86Search) + +# evdev 218 (0xda): no evdev -> QKeyCode mapping (xkb keysym XF86Go) + +# evdev 219 (0xdb): no evdev -> QKeyCode mapping (xkb keysym XF86Finance) + +# evdev 220 (0xdc): no evdev -> QKeyCode mapping (xkb keysym XF86Game) + +# evdev 221 (0xdd): no evdev -> QKeyCode mapping (xkb keysym XF86Shop) + +# evdev 222 (0xde): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 223 (0xdf): no evdev -> QKeyCode mapping (xkb keysym Cancel) + +# evdev 224 (0xe0): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessDown) + +# evdev 225 (0xe1): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessUp) + +# evdev 226 (0xe2), QKeyCode "mediaselect", number 0xed +XF86AudioMedia 0xed + +# evdev 227 (0xe3): no evdev -> QKeyCode mapping (xkb keysym XF86Display) + +# evdev 228 (0xe4): no evdev -> QKeyCode mapping (xkb keysym XF86KbdLightOnOff) + +# evdev 229 (0xe5): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessDown) + +# evdev 230 (0xe6): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessUp) + +# evdev 231 (0xe7): no evdev -> QKeyCode mapping (xkb keysym XF86Send) + +# evdev 232 (0xe8): no evdev -> QKeyCode mapping (xkb keysym XF86Reply) + +# evdev 233 (0xe9): no evdev -> QKeyCode mapping (xkb keysym XF86MailForward) + +# evdev 234 (0xea): no evdev -> QKeyCode mapping (xkb keysym XF86Save) + +# evdev 235 (0xeb): no evdev -> QKeyCode mapping (xkb keysym XF86Documents) + +# evdev 236 (0xec): no evdev -> QKeyCode mapping (xkb keysym XF86Battery) + +# evdev 237 (0xed): no evdev -> QKeyCode mapping (xkb keysym XF86Bluetooth) + +# evdev 238 (0xee): no evdev -> QKeyCode mapping (xkb keysym XF86WLAN) + +# evdev 239 (0xef): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 240 (0xf0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 241 (0xf1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 242 (0xf2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 243 (0xf3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 244 (0xf4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 245 (0xf5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 246 (0xf6): no evdev -> QKeyCode mapping (xkb keysym 0x0edd0160) + +# evdev 247 (0xf7): no evdev -> QKeyCode mapping (xkb keysym 0x0edd0270) + +# +# quirks section start +# +# Sometimes multiple keysyms map to the same keycodes. +# The keycode -> keysym lookup finds only one of the +# keysyms. So append them here. +# + +Print 0x54 +Sys_Req 0x54 +Execute 0x54 +KP_Decimal 0x53 numlock +KP_Separator 0x53 numlock +Alt_R 0xb8 +ISO_Level3_Shift 0xb8 +Mode_switch 0xb8 + +# quirks section end diff --git a/app/src/main/assets/roms/keymaps/de b/app/src/main/assets/roms/keymaps/de new file mode 100644 index 0000000..261243e --- /dev/null +++ b/app/src/main/assets/roms/keymaps/de @@ -0,0 +1,840 @@ +# +# generated by qemu-keymap +# model : pc105 +# layout : de +# variant : nodeadkeys +# options : - + +# name: "German (no dead keys)" + +# modifiers +# 0: Shift +# 1: Lock +# 2: Control +# 3: Mod1 +# 4: Mod2 +# 5: Mod3 +# 6: Mod4 +# 7: Mod5 +# 8: NumLock +# 9: Alt +# 10: LevelThree +# 11: LAlt +# 12: RAlt +# 13: RControl +# 14: LControl +# 15: ScrollLock +# 16: LevelFive +# 17: AltGr +# 18: Meta +# 19: Super +# 20: Hyper + +# evdev 1 (0x1), QKeyCode "esc", number 0x1 +Escape 0x01 + +# evdev 2 (0x2), QKeyCode "1", number 0x2 +1 0x02 +exclam 0x02 shift +onesuperior 0x02 altgr +exclamdown 0x02 shift altgr + +# evdev 3 (0x3), QKeyCode "2", number 0x3 +2 0x03 +quotedbl 0x03 shift +twosuperior 0x03 altgr +oneeighth 0x03 shift altgr + +# evdev 4 (0x4), QKeyCode "3", number 0x4 +3 0x04 +section 0x04 shift +threesuperior 0x04 altgr +sterling 0x04 shift altgr + +# evdev 5 (0x5), QKeyCode "4", number 0x5 +4 0x05 +dollar 0x05 shift +onequarter 0x05 altgr +currency 0x05 shift altgr + +# evdev 6 (0x6), QKeyCode "5", number 0x6 +5 0x06 +percent 0x06 shift +onehalf 0x06 altgr +threeeighths 0x06 shift altgr + +# evdev 7 (0x7), QKeyCode "6", number 0x7 +6 0x07 +ampersand 0x07 shift +notsign 0x07 altgr +fiveeighths 0x07 shift altgr + +# evdev 8 (0x8), QKeyCode "7", number 0x8 +7 0x08 +slash 0x08 shift +braceleft 0x08 altgr +seveneighths 0x08 shift altgr + +# evdev 9 (0x9), QKeyCode "8", number 0x9 +8 0x09 +parenleft 0x09 shift +bracketleft 0x09 altgr +trademark 0x09 shift altgr + +# evdev 10 (0xa), QKeyCode "9", number 0xa +9 0x0a +parenright 0x0a shift +bracketright 0x0a altgr +plusminus 0x0a shift altgr + +# evdev 11 (0xb), QKeyCode "0", number 0xb +0 0x0b +equal 0x0b shift +braceright 0x0b altgr +degree 0x0b shift altgr + +# evdev 12 (0xc), QKeyCode "minus", number 0xc +ssharp 0x0c +question 0x0c shift +backslash 0x0c altgr +questiondown 0x0c shift altgr + +# evdev 13 (0xd), QKeyCode "equal", number 0xd +acute 0x0d +grave 0x0d shift +cedilla 0x0d altgr + +# evdev 14 (0xe), QKeyCode "backspace", number 0xe +BackSpace 0x0e + +# evdev 15 (0xf), QKeyCode "tab", number 0xf +Tab 0x0f +ISO_Left_Tab 0x0f shift + +# evdev 16 (0x10), QKeyCode "q", number 0x10 +q 0x10 +Q 0x10 shift +at 0x10 altgr +Greek_OMEGA 0x10 shift altgr + +# evdev 17 (0x11), QKeyCode "w", number 0x11 +w 0x11 +W 0x11 shift +lstroke 0x11 altgr +Lstroke 0x11 shift altgr + +# evdev 18 (0x12), QKeyCode "e", number 0x12 +e 0x12 +E 0x12 shift +EuroSign 0x12 altgr + +# evdev 19 (0x13), QKeyCode "r", number 0x13 +r 0x13 +R 0x13 shift +paragraph 0x13 altgr +registered 0x13 shift altgr + +# evdev 20 (0x14), QKeyCode "t", number 0x14 +t 0x14 +T 0x14 shift +tslash 0x14 altgr +Tslash 0x14 shift altgr + +# evdev 21 (0x15), QKeyCode "y", number 0x15 +z 0x15 +Z 0x15 shift +leftarrow 0x15 altgr +yen 0x15 shift altgr + +# evdev 22 (0x16), QKeyCode "u", number 0x16 +u 0x16 +U 0x16 shift +downarrow 0x16 altgr +uparrow 0x16 shift altgr + +# evdev 23 (0x17), QKeyCode "i", number 0x17 +i 0x17 +I 0x17 shift +rightarrow 0x17 altgr +idotless 0x17 shift altgr + +# evdev 24 (0x18), QKeyCode "o", number 0x18 +o 0x18 +O 0x18 shift +oslash 0x18 altgr +Oslash 0x18 shift altgr + +# evdev 25 (0x19), QKeyCode "p", number 0x19 +p 0x19 +P 0x19 shift +thorn 0x19 altgr +THORN 0x19 shift altgr + +# evdev 26 (0x1a), QKeyCode "bracket_left", number 0x1a +udiaeresis 0x1a +Udiaeresis 0x1a shift +diaeresis 0x1a altgr + +# evdev 27 (0x1b), QKeyCode "bracket_right", number 0x1b +plus 0x1b +asterisk 0x1b shift +asciitilde 0x1b altgr +macron 0x1b shift altgr + +# evdev 28 (0x1c), QKeyCode "ret", number 0x1c +Return 0x1c + +# evdev 29 (0x1d), QKeyCode "ctrl", number 0x1d +Control_L 0x1d + +# evdev 30 (0x1e), QKeyCode "a", number 0x1e +a 0x1e +A 0x1e shift +ae 0x1e altgr +AE 0x1e shift altgr + +# evdev 31 (0x1f), QKeyCode "s", number 0x1f +s 0x1f +S 0x1f shift +U017F 0x1f altgr +U1E9E 0x1f shift altgr + +# evdev 32 (0x20), QKeyCode "d", number 0x20 +d 0x20 +D 0x20 shift +eth 0x20 altgr +ETH 0x20 shift altgr + +# evdev 33 (0x21), QKeyCode "f", number 0x21 +f 0x21 +F 0x21 shift +dstroke 0x21 altgr +ordfeminine 0x21 shift altgr + +# evdev 34 (0x22), QKeyCode "g", number 0x22 +g 0x22 +G 0x22 shift +eng 0x22 altgr +ENG 0x22 shift altgr + +# evdev 35 (0x23), QKeyCode "h", number 0x23 +h 0x23 +H 0x23 shift +hstroke 0x23 altgr +Hstroke 0x23 shift altgr + +# evdev 36 (0x24), QKeyCode "j", number 0x24 +j 0x24 +J 0x24 shift +dead_belowdot 0x24 altgr +dead_abovedot 0x24 shift altgr + +# evdev 37 (0x25), QKeyCode "k", number 0x25 +k 0x25 +K 0x25 shift +kra 0x25 altgr +ampersand 0x25 shift altgr + +# evdev 38 (0x26), QKeyCode "l", number 0x26 +l 0x26 +L 0x26 shift +lstroke 0x26 altgr +Lstroke 0x26 shift altgr + +# evdev 39 (0x27), QKeyCode "semicolon", number 0x27 +odiaeresis 0x27 +Odiaeresis 0x27 shift +doubleacute 0x27 altgr + +# evdev 40 (0x28), QKeyCode "apostrophe", number 0x28 +adiaeresis 0x28 +Adiaeresis 0x28 shift +asciicircum 0x28 altgr + +# evdev 41 (0x29), QKeyCode "grave_accent", number 0x29 +asciicircum 0x29 +degree 0x29 shift +notsign 0x29 altgr + +# evdev 42 (0x2a), QKeyCode "shift", number 0x2a +Shift_L 0x2a + +# evdev 43 (0x2b), QKeyCode "backslash", number 0x2b +numbersign 0x2b +apostrophe 0x2b shift +rightsinglequotemark 0x2b altgr +grave 0x2b shift altgr + +# evdev 44 (0x2c), QKeyCode "z", number 0x2c +y 0x2c +Y 0x2c shift +guillemotright 0x2c altgr +U203A 0x2c shift altgr + +# evdev 45 (0x2d), QKeyCode "x", number 0x2d +x 0x2d +X 0x2d shift +guillemotleft 0x2d altgr +U2039 0x2d shift altgr + +# evdev 46 (0x2e), QKeyCode "c", number 0x2e +c 0x2e +C 0x2e shift +cent 0x2e altgr +copyright 0x2e shift altgr + +# evdev 47 (0x2f), QKeyCode "v", number 0x2f +v 0x2f +V 0x2f shift +doublelowquotemark 0x2f altgr +singlelowquotemark 0x2f shift altgr + +# evdev 48 (0x30), QKeyCode "b", number 0x30 +b 0x30 +B 0x30 shift +leftdoublequotemark 0x30 altgr +leftsinglequotemark 0x30 shift altgr + +# evdev 49 (0x31), QKeyCode "n", number 0x31 +n 0x31 +N 0x31 shift +rightdoublequotemark 0x31 altgr +rightsinglequotemark 0x31 shift altgr + +# evdev 50 (0x32), QKeyCode "m", number 0x32 +m 0x32 +M 0x32 shift +mu 0x32 altgr +masculine 0x32 shift altgr + +# evdev 51 (0x33), QKeyCode "comma", number 0x33 +comma 0x33 +semicolon 0x33 shift +periodcentered 0x33 altgr +multiply 0x33 shift altgr + +# evdev 52 (0x34), QKeyCode "dot", number 0x34 +period 0x34 +colon 0x34 shift +U2026 0x34 altgr +division 0x34 shift altgr + +# evdev 53 (0x35), QKeyCode "slash", number 0x35 +minus 0x35 +underscore 0x35 shift +endash 0x35 altgr +emdash 0x35 shift altgr + +# evdev 54 (0x36), QKeyCode "shift_r", number 0x36 +Shift_R 0x36 + +# evdev 55 (0x37), QKeyCode "kp_multiply", number 0x37 +KP_Multiply 0x37 + +# evdev 56 (0x38), QKeyCode "alt", number 0x38 +Alt_L 0x38 +Meta_L 0x38 shift + +# evdev 57 (0x39), QKeyCode "spc", number 0x39 +space 0x39 + +# evdev 58 (0x3a), QKeyCode "caps_lock", number 0x3a +Caps_Lock 0x3a + +# evdev 59 (0x3b), QKeyCode "f1", number 0x3b +F1 0x3b + +# evdev 60 (0x3c), QKeyCode "f2", number 0x3c +F2 0x3c + +# evdev 61 (0x3d), QKeyCode "f3", number 0x3d +F3 0x3d + +# evdev 62 (0x3e), QKeyCode "f4", number 0x3e +F4 0x3e + +# evdev 63 (0x3f), QKeyCode "f5", number 0x3f +F5 0x3f + +# evdev 64 (0x40), QKeyCode "f6", number 0x40 +F6 0x40 + +# evdev 65 (0x41), QKeyCode "f7", number 0x41 +F7 0x41 + +# evdev 66 (0x42), QKeyCode "f8", number 0x42 +F8 0x42 + +# evdev 67 (0x43), QKeyCode "f9", number 0x43 +F9 0x43 + +# evdev 68 (0x44), QKeyCode "f10", number 0x44 +F10 0x44 + +# evdev 69 (0x45), QKeyCode "num_lock", number 0x45 +Num_Lock 0x45 + +# evdev 70 (0x46), QKeyCode "scroll_lock", number 0x46 +Scroll_Lock 0x46 + +# evdev 71 (0x47), QKeyCode "kp_7", number 0x47 +KP_Home 0x47 +KP_7 0x47 numlock + +# evdev 72 (0x48), QKeyCode "kp_8", number 0x48 +KP_Up 0x48 +KP_8 0x48 numlock + +# evdev 73 (0x49), QKeyCode "kp_9", number 0x49 +KP_Prior 0x49 +KP_9 0x49 numlock + +# evdev 74 (0x4a), QKeyCode "kp_subtract", number 0x4a +KP_Subtract 0x4a + +# evdev 75 (0x4b), QKeyCode "kp_4", number 0x4b +KP_Left 0x4b +KP_4 0x4b numlock + +# evdev 76 (0x4c), QKeyCode "kp_5", number 0x4c +KP_Begin 0x4c +KP_5 0x4c numlock + +# evdev 77 (0x4d), QKeyCode "kp_6", number 0x4d +KP_Right 0x4d +KP_6 0x4d numlock + +# evdev 78 (0x4e), QKeyCode "kp_add", number 0x4e +KP_Add 0x4e + +# evdev 79 (0x4f), QKeyCode "kp_1", number 0x4f +KP_End 0x4f +KP_1 0x4f numlock + +# evdev 80 (0x50), QKeyCode "kp_2", number 0x50 +KP_Down 0x50 +KP_2 0x50 numlock + +# evdev 81 (0x51), QKeyCode "kp_3", number 0x51 +KP_Next 0x51 +KP_3 0x51 numlock + +# evdev 82 (0x52), QKeyCode "kp_0", number 0x52 +KP_Insert 0x52 +KP_0 0x52 numlock + +# evdev 83 (0x53), QKeyCode "kp_decimal", number 0x53 +KP_Delete 0x53 +KP_Separator 0x53 numlock + +# evdev 84 (0x54): no evdev -> QKeyCode mapping (xkb keysym ISO_Level3_Shift) + +# evdev 85 (0x55): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 86 (0x56), QKeyCode "less", number 0x56 +less 0x56 +greater 0x56 shift +bar 0x56 altgr +dead_belowmacron 0x56 shift altgr + +# evdev 87 (0x57), QKeyCode "f11", number 0x57 +F11 0x57 + +# evdev 88 (0x58), QKeyCode "f12", number 0x58 +F12 0x58 + +# evdev 89 (0x59), QKeyCode "ro", number 0x73 + +# evdev 90 (0x5a): no evdev -> QKeyCode mapping (xkb keysym Katakana) + +# evdev 91 (0x5b), QKeyCode "hiragana", number 0x77 +Hiragana 0x77 + +# evdev 92 (0x5c), QKeyCode "henkan", number 0x79 +Henkan_Mode 0x79 + +# evdev 93 (0x5d), QKeyCode "katakanahiragana", number 0x70 +Hiragana_Katakana 0x70 + +# evdev 94 (0x5e), QKeyCode "muhenkan", number 0x7b +Muhenkan 0x7b + +# evdev 95 (0x5f): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 96 (0x60), QKeyCode "kp_enter", number 0x9c +KP_Enter 0x9c + +# evdev 97 (0x61), QKeyCode "ctrl_r", number 0x9d +Control_R 0x9d + +# evdev 98 (0x62), QKeyCode "kp_divide", number 0xb5 +KP_Divide 0xb5 + +# evdev 99 (0x63), QKeyCode "sysrq", number 0x54 +Print 0x54 + +# evdev 100 (0x64), QKeyCode "alt_r", number 0xb8 +ISO_Level3_Shift 0xb8 + +# evdev 101 (0x65), QKeyCode "lf", number 0x5b +Linefeed 0x5b + +# evdev 102 (0x66), QKeyCode "home", number 0xc7 +Home 0xc7 + +# evdev 103 (0x67), QKeyCode "up", number 0xc8 +Up 0xc8 + +# evdev 104 (0x68), QKeyCode "pgup", number 0xc9 +Prior 0xc9 + +# evdev 105 (0x69), QKeyCode "left", number 0xcb +Left 0xcb + +# evdev 106 (0x6a), QKeyCode "right", number 0xcd +Right 0xcd + +# evdev 107 (0x6b), QKeyCode "end", number 0xcf +End 0xcf + +# evdev 108 (0x6c), QKeyCode "down", number 0xd0 +Down 0xd0 + +# evdev 109 (0x6d), QKeyCode "pgdn", number 0xd1 +Next 0xd1 + +# evdev 110 (0x6e), QKeyCode "insert", number 0xd2 +Insert 0xd2 + +# evdev 111 (0x6f), QKeyCode "delete", number 0xd3 +Delete 0xd3 + +# evdev 112 (0x70): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 113 (0x71), QKeyCode "audiomute", number 0xa0 +XF86AudioMute 0xa0 + +# evdev 114 (0x72), QKeyCode "volumedown", number 0xae +XF86AudioLowerVolume 0xae + +# evdev 115 (0x73), QKeyCode "volumeup", number 0xb0 +XF86AudioRaiseVolume 0xb0 + +# evdev 116 (0x74), QKeyCode "power", number 0xde +XF86PowerOff 0xde + +# evdev 117 (0x75), QKeyCode "kp_equals", number 0x59 +KP_Equal 0x59 + +# evdev 118 (0x76): no evdev -> QKeyCode mapping (xkb keysym plusminus) + +# evdev 119 (0x77), QKeyCode "pause", number 0xc6 +Pause 0xc6 + +# evdev 120 (0x78): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchA) + +# evdev 121 (0x79), QKeyCode "kp_comma", number 0x7e +KP_Decimal 0x7e + +# evdev 122 (0x7a): no evdev -> QKeyCode mapping (xkb keysym Hangul) + +# evdev 123 (0x7b): no evdev -> QKeyCode mapping (xkb keysym Hangul_Hanja) + +# evdev 124 (0x7c), QKeyCode "yen", number 0x7d + +# evdev 125 (0x7d), QKeyCode "meta_l", number 0xdb +Super_L 0xdb + +# evdev 126 (0x7e), QKeyCode "meta_r", number 0xdc +Super_R 0xdc + +# evdev 127 (0x7f), QKeyCode "compose", number 0xdd +Menu 0xdd + +# evdev 128 (0x80), QKeyCode "stop", number 0xe8 +Cancel 0xe8 + +# evdev 129 (0x81), QKeyCode "again", number 0x85 +Redo 0x85 + +# evdev 130 (0x82), QKeyCode "props", number 0x86 +SunProps 0x86 + +# evdev 131 (0x83), QKeyCode "undo", number 0x87 +Undo 0x87 + +# evdev 132 (0x84), QKeyCode "front", number 0x8c +SunFront 0x8c + +# evdev 133 (0x85), QKeyCode "copy", number 0xf8 +XF86Copy 0xf8 + +# evdev 134 (0x86), QKeyCode "open", number 0x64 +XF86Open 0x64 + +# evdev 135 (0x87), QKeyCode "paste", number 0x65 +XF86Paste 0x65 + +# evdev 136 (0x88), QKeyCode "find", number 0xc1 +Find 0xc1 + +# evdev 137 (0x89), QKeyCode "cut", number 0xbc +XF86Cut 0xbc + +# evdev 138 (0x8a), QKeyCode "help", number 0xf5 +Help 0xf5 + +# evdev 139 (0x8b), QKeyCode "menu", number 0x9e +XF86MenuKB 0x9e + +# evdev 140 (0x8c), QKeyCode "calculator", number 0xa1 +XF86Calculator 0xa1 + +# evdev 141 (0x8d): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 142 (0x8e), QKeyCode "sleep", number 0xdf +XF86Sleep 0xdf + +# evdev 143 (0x8f), QKeyCode "wake", number 0xe3 +XF86WakeUp 0xe3 + +# evdev 144 (0x90): no evdev -> QKeyCode mapping (xkb keysym XF86Explorer) + +# evdev 145 (0x91): no evdev -> QKeyCode mapping (xkb keysym XF86Send) + +# evdev 146 (0x92): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 147 (0x93): no evdev -> QKeyCode mapping (xkb keysym XF86Xfer) + +# evdev 148 (0x94): no evdev -> QKeyCode mapping (xkb keysym XF86Launch1) + +# evdev 149 (0x95): no evdev -> QKeyCode mapping (xkb keysym XF86Launch2) + +# evdev 150 (0x96): no evdev -> QKeyCode mapping (xkb keysym XF86WWW) + +# evdev 151 (0x97): no evdev -> QKeyCode mapping (xkb keysym XF86DOS) + +# evdev 152 (0x98): no evdev -> QKeyCode mapping (xkb keysym XF86ScreenSaver) + +# evdev 153 (0x99): no evdev -> QKeyCode mapping (xkb keysym XF86RotateWindows) + +# evdev 154 (0x9a): no evdev -> QKeyCode mapping (xkb keysym XF86TaskPane) + +# evdev 155 (0x9b), QKeyCode "mail", number 0xec +XF86Mail 0xec + +# evdev 156 (0x9c), QKeyCode "ac_bookmarks", number 0xe6 +XF86Favorites 0xe6 + +# evdev 157 (0x9d), QKeyCode "computer", number 0xeb +XF86MyComputer 0xeb + +# evdev 158 (0x9e), QKeyCode "ac_back", number 0xea +XF86Back 0xea + +# evdev 159 (0x9f), QKeyCode "ac_forward", number 0xe9 +XF86Forward 0xe9 + +# evdev 160 (0xa0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 161 (0xa1): no evdev -> QKeyCode mapping (xkb keysym XF86Eject) + +# evdev 162 (0xa2): no evdev -> QKeyCode mapping (xkb keysym XF86Eject) + +# evdev 163 (0xa3), QKeyCode "audionext", number 0x99 +XF86AudioNext 0x99 + +# evdev 164 (0xa4), QKeyCode "audioplay", number 0xa2 +XF86AudioPlay 0xa2 +XF86AudioPause 0xa2 shift + +# evdev 165 (0xa5), QKeyCode "audioprev", number 0x90 +XF86AudioPrev 0x90 + +# evdev 166 (0xa6), QKeyCode "audiostop", number 0xa4 +XF86AudioStop 0xa4 +XF86Eject 0xa4 shift + +# evdev 167 (0xa7): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRecord) + +# evdev 168 (0xa8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRewind) + +# evdev 169 (0xa9): no evdev -> QKeyCode mapping (xkb keysym XF86Phone) + +# evdev 170 (0xaa): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 171 (0xab): no evdev -> QKeyCode mapping (xkb keysym XF86Tools) + +# evdev 172 (0xac), QKeyCode "ac_home", number 0xb2 +XF86HomePage 0xb2 + +# evdev 173 (0xad), QKeyCode "ac_refresh", number 0xe7 +XF86Reload 0xe7 + +# evdev 174 (0xae): no evdev -> QKeyCode mapping (xkb keysym XF86Close) + +# evdev 175 (0xaf): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 176 (0xb0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 177 (0xb1): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollUp) + +# evdev 178 (0xb2): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollDown) + +# evdev 179 (0xb3): no evdev -> QKeyCode mapping (xkb keysym parenleft) + +# evdev 180 (0xb4): no evdev -> QKeyCode mapping (xkb keysym parenright) + +# evdev 181 (0xb5): no evdev -> QKeyCode mapping (xkb keysym XF86New) + +# evdev 182 (0xb6): no evdev -> QKeyCode mapping (xkb keysym Redo) + +# evdev 183 (0xb7): no evdev -> QKeyCode mapping (xkb keysym XF86Tools) + +# evdev 184 (0xb8): no evdev -> QKeyCode mapping (xkb keysym XF86Launch5) + +# evdev 185 (0xb9): no evdev -> QKeyCode mapping (xkb keysym XF86Launch6) + +# evdev 186 (0xba): no evdev -> QKeyCode mapping (xkb keysym XF86Launch7) + +# evdev 187 (0xbb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch8) + +# evdev 188 (0xbc): no evdev -> QKeyCode mapping (xkb keysym XF86Launch9) + +# evdev 189 (0xbd): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 190 (0xbe): no evdev -> QKeyCode mapping (xkb keysym XF86AudioMicMute) + +# evdev 191 (0xbf): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadToggle) + +# evdev 192 (0xc0): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOn) + +# evdev 193 (0xc1): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOff) + +# evdev 194 (0xc2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 195 (0xc3): no evdev -> QKeyCode mapping (xkb keysym Mode_switch) + +# evdev 196 (0xc4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 197 (0xc5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 198 (0xc6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 199 (0xc7): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 200 (0xc8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay) + +# evdev 201 (0xc9): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPause) + +# evdev 202 (0xca): no evdev -> QKeyCode mapping (xkb keysym XF86Launch3) + +# evdev 203 (0xcb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch4) + +# evdev 204 (0xcc): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchB) + +# evdev 205 (0xcd): no evdev -> QKeyCode mapping (xkb keysym XF86Suspend) + +# evdev 206 (0xce): no evdev -> QKeyCode mapping (xkb keysym XF86Close) + +# evdev 207 (0xcf): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay) + +# evdev 208 (0xd0): no evdev -> QKeyCode mapping (xkb keysym XF86AudioForward) + +# evdev 209 (0xd1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 210 (0xd2): no evdev -> QKeyCode mapping (xkb keysym Print) + +# evdev 211 (0xd3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 212 (0xd4): no evdev -> QKeyCode mapping (xkb keysym XF86WebCam) + +# evdev 213 (0xd5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 214 (0xd6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 215 (0xd7): no evdev -> QKeyCode mapping (xkb keysym XF86Mail) + +# evdev 216 (0xd8): no evdev -> QKeyCode mapping (xkb keysym XF86Messenger) + +# evdev 217 (0xd9): no evdev -> QKeyCode mapping (xkb keysym XF86Search) + +# evdev 218 (0xda): no evdev -> QKeyCode mapping (xkb keysym XF86Go) + +# evdev 219 (0xdb): no evdev -> QKeyCode mapping (xkb keysym XF86Finance) + +# evdev 220 (0xdc): no evdev -> QKeyCode mapping (xkb keysym XF86Game) + +# evdev 221 (0xdd): no evdev -> QKeyCode mapping (xkb keysym XF86Shop) + +# evdev 222 (0xde): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 223 (0xdf): no evdev -> QKeyCode mapping (xkb keysym Cancel) + +# evdev 224 (0xe0): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessDown) + +# evdev 225 (0xe1): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessUp) + +# evdev 226 (0xe2), QKeyCode "mediaselect", number 0xed +XF86AudioMedia 0xed + +# evdev 227 (0xe3): no evdev -> QKeyCode mapping (xkb keysym XF86Display) + +# evdev 228 (0xe4): no evdev -> QKeyCode mapping (xkb keysym XF86KbdLightOnOff) + +# evdev 229 (0xe5): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessDown) + +# evdev 230 (0xe6): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessUp) + +# evdev 231 (0xe7): no evdev -> QKeyCode mapping (xkb keysym XF86Send) + +# evdev 232 (0xe8): no evdev -> QKeyCode mapping (xkb keysym XF86Reply) + +# evdev 233 (0xe9): no evdev -> QKeyCode mapping (xkb keysym XF86MailForward) + +# evdev 234 (0xea): no evdev -> QKeyCode mapping (xkb keysym XF86Save) + +# evdev 235 (0xeb): no evdev -> QKeyCode mapping (xkb keysym XF86Documents) + +# evdev 236 (0xec): no evdev -> QKeyCode mapping (xkb keysym XF86Battery) + +# evdev 237 (0xed): no evdev -> QKeyCode mapping (xkb keysym XF86Bluetooth) + +# evdev 238 (0xee): no evdev -> QKeyCode mapping (xkb keysym XF86WLAN) + +# evdev 239 (0xef): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 240 (0xf0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 241 (0xf1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 242 (0xf2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 243 (0xf3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 244 (0xf4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 245 (0xf5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 246 (0xf6): no evdev -> QKeyCode mapping (xkb keysym Invalid) + +# evdev 247 (0xf7): no evdev -> QKeyCode mapping (xkb keysym Invalid) + +# +# quirks section start +# +# Sometimes multiple keysyms map to the same keycodes. +# The keycode -> keysym lookup finds only one of the +# keysyms. So append them here. +# + +Print 0x54 +Sys_Req 0x54 +Execute 0x54 +KP_Decimal 0x53 numlock +KP_Separator 0x53 numlock +Alt_R 0xb8 +ISO_Level3_Shift 0xb8 +Mode_switch 0xb8 + +# quirks section end diff --git a/app/src/main/assets/roms/keymaps/de-ch b/app/src/main/assets/roms/keymaps/de-ch new file mode 100644 index 0000000..ed3da05 --- /dev/null +++ b/app/src/main/assets/roms/keymaps/de-ch @@ -0,0 +1,842 @@ +# +# generated by qemu-keymap +# model : pc105 +# layout : ch +# variant : - +# options : - + +# name: "German (Switzerland)" + +# modifiers +# 0: Shift +# 1: Lock +# 2: Control +# 3: Mod1 +# 4: Mod2 +# 5: Mod3 +# 6: Mod4 +# 7: Mod5 +# 8: NumLock +# 9: Alt +# 10: LevelThree +# 11: LAlt +# 12: RAlt +# 13: RControl +# 14: LControl +# 15: ScrollLock +# 16: LevelFive +# 17: AltGr +# 18: Meta +# 19: Super +# 20: Hyper + +# evdev 1 (0x1), QKeyCode "esc", number 0x1 +Escape 0x01 + +# evdev 2 (0x2), QKeyCode "1", number 0x2 +1 0x02 +plus 0x02 shift +bar 0x02 altgr +exclamdown 0x02 shift altgr + +# evdev 3 (0x3), QKeyCode "2", number 0x3 +2 0x03 +quotedbl 0x03 shift +at 0x03 altgr +oneeighth 0x03 shift altgr + +# evdev 4 (0x4), QKeyCode "3", number 0x4 +3 0x04 +asterisk 0x04 shift +numbersign 0x04 altgr +sterling 0x04 shift altgr + +# evdev 5 (0x5), QKeyCode "4", number 0x5 +4 0x05 +ccedilla 0x05 shift +onequarter 0x05 altgr +dollar 0x05 shift altgr + +# evdev 6 (0x6), QKeyCode "5", number 0x6 +5 0x06 +percent 0x06 shift +onehalf 0x06 altgr +threeeighths 0x06 shift altgr + +# evdev 7 (0x7), QKeyCode "6", number 0x7 +6 0x07 +ampersand 0x07 shift +notsign 0x07 altgr +fiveeighths 0x07 shift altgr + +# evdev 8 (0x8), QKeyCode "7", number 0x8 +7 0x08 +slash 0x08 shift +bar 0x08 altgr +seveneighths 0x08 shift altgr + +# evdev 9 (0x9), QKeyCode "8", number 0x9 +8 0x09 +parenleft 0x09 shift +cent 0x09 altgr +trademark 0x09 shift altgr + +# evdev 10 (0xa), QKeyCode "9", number 0xa +9 0x0a +parenright 0x0a shift +bracketright 0x0a altgr +plusminus 0x0a shift altgr + +# evdev 11 (0xb), QKeyCode "0", number 0xb +0 0x0b +equal 0x0b shift +braceright 0x0b altgr +degree 0x0b shift altgr + +# evdev 12 (0xc), QKeyCode "minus", number 0xc +apostrophe 0x0c +question 0x0c shift +dead_acute 0x0c altgr +questiondown 0x0c shift altgr + +# evdev 13 (0xd), QKeyCode "equal", number 0xd +dead_circumflex 0x0d +dead_grave 0x0d shift +dead_tilde 0x0d altgr +dead_ogonek 0x0d shift altgr + +# evdev 14 (0xe), QKeyCode "backspace", number 0xe +BackSpace 0x0e + +# evdev 15 (0xf), QKeyCode "tab", number 0xf +Tab 0x0f +ISO_Left_Tab 0x0f shift + +# evdev 16 (0x10), QKeyCode "q", number 0x10 +q 0x10 +Q 0x10 shift +at 0x10 altgr +Greek_OMEGA 0x10 shift altgr + +# evdev 17 (0x11), QKeyCode "w", number 0x11 +w 0x11 +W 0x11 shift +lstroke 0x11 altgr +Lstroke 0x11 shift altgr + +# evdev 18 (0x12), QKeyCode "e", number 0x12 +e 0x12 +E 0x12 shift +EuroSign 0x12 altgr + +# evdev 19 (0x13), QKeyCode "r", number 0x13 +r 0x13 +R 0x13 shift +paragraph 0x13 altgr +registered 0x13 shift altgr + +# evdev 20 (0x14), QKeyCode "t", number 0x14 +t 0x14 +T 0x14 shift +tslash 0x14 altgr +Tslash 0x14 shift altgr + +# evdev 21 (0x15), QKeyCode "y", number 0x15 +z 0x15 +Z 0x15 shift +leftarrow 0x15 altgr +yen 0x15 shift altgr + +# evdev 22 (0x16), QKeyCode "u", number 0x16 +u 0x16 +U 0x16 shift +downarrow 0x16 altgr +uparrow 0x16 shift altgr + +# evdev 23 (0x17), QKeyCode "i", number 0x17 +i 0x17 +I 0x17 shift +rightarrow 0x17 altgr +idotless 0x17 shift altgr + +# evdev 24 (0x18), QKeyCode "o", number 0x18 +o 0x18 +O 0x18 shift +oe 0x18 altgr +OE 0x18 shift altgr + +# evdev 25 (0x19), QKeyCode "p", number 0x19 +p 0x19 +P 0x19 shift +thorn 0x19 altgr +THORN 0x19 shift altgr + +# evdev 26 (0x1a), QKeyCode "bracket_left", number 0x1a +udiaeresis 0x1a +egrave 0x1a shift +bracketleft 0x1a altgr +dead_abovering 0x1a shift altgr + +# evdev 27 (0x1b), QKeyCode "bracket_right", number 0x1b +dead_diaeresis 0x1b +exclam 0x1b shift +bracketright 0x1b altgr +dead_macron 0x1b shift altgr + +# evdev 28 (0x1c), QKeyCode "ret", number 0x1c +Return 0x1c + +# evdev 29 (0x1d), QKeyCode "ctrl", number 0x1d +Control_L 0x1d + +# evdev 30 (0x1e), QKeyCode "a", number 0x1e +a 0x1e +A 0x1e shift +ae 0x1e altgr +AE 0x1e shift altgr + +# evdev 31 (0x1f), QKeyCode "s", number 0x1f +s 0x1f +S 0x1f shift +ssharp 0x1f altgr +section 0x1f shift altgr + +# evdev 32 (0x20), QKeyCode "d", number 0x20 +d 0x20 +D 0x20 shift +eth 0x20 altgr +ETH 0x20 shift altgr + +# evdev 33 (0x21), QKeyCode "f", number 0x21 +f 0x21 +F 0x21 shift +dstroke 0x21 altgr +ordfeminine 0x21 shift altgr + +# evdev 34 (0x22), QKeyCode "g", number 0x22 +g 0x22 +G 0x22 shift +eng 0x22 altgr +ENG 0x22 shift altgr + +# evdev 35 (0x23), QKeyCode "h", number 0x23 +h 0x23 +H 0x23 shift +hstroke 0x23 altgr +Hstroke 0x23 shift altgr + +# evdev 36 (0x24), QKeyCode "j", number 0x24 +j 0x24 +J 0x24 shift +dead_hook 0x24 altgr +dead_horn 0x24 shift altgr + +# evdev 37 (0x25), QKeyCode "k", number 0x25 +k 0x25 +K 0x25 shift +kra 0x25 altgr +ampersand 0x25 shift altgr + +# evdev 38 (0x26), QKeyCode "l", number 0x26 +l 0x26 +L 0x26 shift +lstroke 0x26 altgr +Lstroke 0x26 shift altgr + +# evdev 39 (0x27), QKeyCode "semicolon", number 0x27 +odiaeresis 0x27 +eacute 0x27 shift +dead_acute 0x27 altgr +dead_doubleacute 0x27 shift altgr + +# evdev 40 (0x28), QKeyCode "apostrophe", number 0x28 +adiaeresis 0x28 +agrave 0x28 shift +braceleft 0x28 altgr +dead_caron 0x28 shift altgr + +# evdev 41 (0x29), QKeyCode "grave_accent", number 0x29 +section 0x29 +degree 0x29 shift +notsign 0x29 altgr + +# evdev 42 (0x2a), QKeyCode "shift", number 0x2a +Shift_L 0x2a + +# evdev 43 (0x2b), QKeyCode "backslash", number 0x2b +dollar 0x2b +sterling 0x2b shift +braceright 0x2b altgr +dead_breve 0x2b shift altgr + +# evdev 44 (0x2c), QKeyCode "z", number 0x2c +y 0x2c +Y 0x2c shift +guillemotleft 0x2c altgr +less 0x2c shift altgr + +# evdev 45 (0x2d), QKeyCode "x", number 0x2d +x 0x2d +X 0x2d shift +guillemotright 0x2d altgr +greater 0x2d shift altgr + +# evdev 46 (0x2e), QKeyCode "c", number 0x2e +c 0x2e +C 0x2e shift +cent 0x2e altgr +copyright 0x2e shift altgr + +# evdev 47 (0x2f), QKeyCode "v", number 0x2f +v 0x2f +V 0x2f shift +leftdoublequotemark 0x2f altgr +leftsinglequotemark 0x2f shift altgr + +# evdev 48 (0x30), QKeyCode "b", number 0x30 +b 0x30 +B 0x30 shift +rightdoublequotemark 0x30 altgr +rightsinglequotemark 0x30 shift altgr + +# evdev 49 (0x31), QKeyCode "n", number 0x31 +n 0x31 +N 0x31 shift + +# evdev 50 (0x32), QKeyCode "m", number 0x32 +m 0x32 +M 0x32 shift +mu 0x32 altgr +masculine 0x32 shift altgr + +# evdev 51 (0x33), QKeyCode "comma", number 0x33 +comma 0x33 +semicolon 0x33 shift +horizconnector 0x33 altgr +multiply 0x33 shift altgr + +# evdev 52 (0x34), QKeyCode "dot", number 0x34 +period 0x34 +colon 0x34 shift +periodcentered 0x34 altgr +division 0x34 shift altgr + +# evdev 53 (0x35), QKeyCode "slash", number 0x35 +minus 0x35 +underscore 0x35 shift +dead_belowdot 0x35 altgr +dead_abovedot 0x35 shift altgr + +# evdev 54 (0x36), QKeyCode "shift_r", number 0x36 +Shift_R 0x36 + +# evdev 55 (0x37), QKeyCode "kp_multiply", number 0x37 +KP_Multiply 0x37 + +# evdev 56 (0x38), QKeyCode "alt", number 0x38 +Alt_L 0x38 +Meta_L 0x38 shift + +# evdev 57 (0x39), QKeyCode "spc", number 0x39 +space 0x39 + +# evdev 58 (0x3a), QKeyCode "caps_lock", number 0x3a +Caps_Lock 0x3a + +# evdev 59 (0x3b), QKeyCode "f1", number 0x3b +F1 0x3b + +# evdev 60 (0x3c), QKeyCode "f2", number 0x3c +F2 0x3c + +# evdev 61 (0x3d), QKeyCode "f3", number 0x3d +F3 0x3d + +# evdev 62 (0x3e), QKeyCode "f4", number 0x3e +F4 0x3e + +# evdev 63 (0x3f), QKeyCode "f5", number 0x3f +F5 0x3f + +# evdev 64 (0x40), QKeyCode "f6", number 0x40 +F6 0x40 + +# evdev 65 (0x41), QKeyCode "f7", number 0x41 +F7 0x41 + +# evdev 66 (0x42), QKeyCode "f8", number 0x42 +F8 0x42 + +# evdev 67 (0x43), QKeyCode "f9", number 0x43 +F9 0x43 + +# evdev 68 (0x44), QKeyCode "f10", number 0x44 +F10 0x44 + +# evdev 69 (0x45), QKeyCode "num_lock", number 0x45 +Num_Lock 0x45 + +# evdev 70 (0x46), QKeyCode "scroll_lock", number 0x46 +Scroll_Lock 0x46 + +# evdev 71 (0x47), QKeyCode "kp_7", number 0x47 +KP_Home 0x47 +KP_7 0x47 numlock + +# evdev 72 (0x48), QKeyCode "kp_8", number 0x48 +KP_Up 0x48 +KP_8 0x48 numlock + +# evdev 73 (0x49), QKeyCode "kp_9", number 0x49 +KP_Prior 0x49 +KP_9 0x49 numlock + +# evdev 74 (0x4a), QKeyCode "kp_subtract", number 0x4a +KP_Subtract 0x4a + +# evdev 75 (0x4b), QKeyCode "kp_4", number 0x4b +KP_Left 0x4b +KP_4 0x4b numlock + +# evdev 76 (0x4c), QKeyCode "kp_5", number 0x4c +KP_Begin 0x4c +KP_5 0x4c numlock + +# evdev 77 (0x4d), QKeyCode "kp_6", number 0x4d +KP_Right 0x4d +KP_6 0x4d numlock + +# evdev 78 (0x4e), QKeyCode "kp_add", number 0x4e +KP_Add 0x4e + +# evdev 79 (0x4f), QKeyCode "kp_1", number 0x4f +KP_End 0x4f +KP_1 0x4f numlock + +# evdev 80 (0x50), QKeyCode "kp_2", number 0x50 +KP_Down 0x50 +KP_2 0x50 numlock + +# evdev 81 (0x51), QKeyCode "kp_3", number 0x51 +KP_Next 0x51 +KP_3 0x51 numlock + +# evdev 82 (0x52), QKeyCode "kp_0", number 0x52 +KP_Insert 0x52 +KP_0 0x52 numlock + +# evdev 83 (0x53), QKeyCode "kp_decimal", number 0x53 +KP_Delete 0x53 +KP_Decimal 0x53 numlock + +# evdev 84 (0x54): no evdev -> QKeyCode mapping (xkb keysym ISO_Level3_Shift) + +# evdev 85 (0x55): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 86 (0x56), QKeyCode "less", number 0x56 +less 0x56 +greater 0x56 shift +backslash 0x56 altgr +brokenbar 0x56 shift altgr + +# evdev 87 (0x57), QKeyCode "f11", number 0x57 +F11 0x57 + +# evdev 88 (0x58), QKeyCode "f12", number 0x58 +F12 0x58 + +# evdev 89 (0x59), QKeyCode "ro", number 0x73 + +# evdev 90 (0x5a): no evdev -> QKeyCode mapping (xkb keysym Katakana) + +# evdev 91 (0x5b), QKeyCode "hiragana", number 0x77 +Hiragana 0x77 + +# evdev 92 (0x5c), QKeyCode "henkan", number 0x79 +Henkan_Mode 0x79 + +# evdev 93 (0x5d), QKeyCode "katakanahiragana", number 0x70 +Hiragana_Katakana 0x70 + +# evdev 94 (0x5e), QKeyCode "muhenkan", number 0x7b +Muhenkan 0x7b + +# evdev 95 (0x5f): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 96 (0x60), QKeyCode "kp_enter", number 0x9c +KP_Enter 0x9c + +# evdev 97 (0x61), QKeyCode "ctrl_r", number 0x9d +Control_R 0x9d + +# evdev 98 (0x62), QKeyCode "kp_divide", number 0xb5 +KP_Divide 0xb5 + +# evdev 99 (0x63), QKeyCode "sysrq", number 0x54 +Print 0x54 + +# evdev 100 (0x64), QKeyCode "alt_r", number 0xb8 +ISO_Level3_Shift 0xb8 + +# evdev 101 (0x65), QKeyCode "lf", number 0x5b +Linefeed 0x5b + +# evdev 102 (0x66), QKeyCode "home", number 0xc7 +Home 0xc7 + +# evdev 103 (0x67), QKeyCode "up", number 0xc8 +Up 0xc8 + +# evdev 104 (0x68), QKeyCode "pgup", number 0xc9 +Prior 0xc9 + +# evdev 105 (0x69), QKeyCode "left", number 0xcb +Left 0xcb + +# evdev 106 (0x6a), QKeyCode "right", number 0xcd +Right 0xcd + +# evdev 107 (0x6b), QKeyCode "end", number 0xcf +End 0xcf + +# evdev 108 (0x6c), QKeyCode "down", number 0xd0 +Down 0xd0 + +# evdev 109 (0x6d), QKeyCode "pgdn", number 0xd1 +Next 0xd1 + +# evdev 110 (0x6e), QKeyCode "insert", number 0xd2 +Insert 0xd2 + +# evdev 111 (0x6f), QKeyCode "delete", number 0xd3 +Delete 0xd3 + +# evdev 112 (0x70): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 113 (0x71), QKeyCode "audiomute", number 0xa0 +XF86AudioMute 0xa0 + +# evdev 114 (0x72), QKeyCode "volumedown", number 0xae +XF86AudioLowerVolume 0xae + +# evdev 115 (0x73), QKeyCode "volumeup", number 0xb0 +XF86AudioRaiseVolume 0xb0 + +# evdev 116 (0x74), QKeyCode "power", number 0xde +XF86PowerOff 0xde + +# evdev 117 (0x75), QKeyCode "kp_equals", number 0x59 +KP_Equal 0x59 + +# evdev 118 (0x76): no evdev -> QKeyCode mapping (xkb keysym plusminus) + +# evdev 119 (0x77), QKeyCode "pause", number 0xc6 +Pause 0xc6 + +# evdev 120 (0x78): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchA) + +# evdev 121 (0x79), QKeyCode "kp_comma", number 0x7e +KP_Decimal 0x7e + +# evdev 122 (0x7a): no evdev -> QKeyCode mapping (xkb keysym Hangul) + +# evdev 123 (0x7b): no evdev -> QKeyCode mapping (xkb keysym Hangul_Hanja) + +# evdev 124 (0x7c), QKeyCode "yen", number 0x7d + +# evdev 125 (0x7d), QKeyCode "meta_l", number 0xdb +Super_L 0xdb + +# evdev 126 (0x7e), QKeyCode "meta_r", number 0xdc +Super_R 0xdc + +# evdev 127 (0x7f), QKeyCode "compose", number 0xdd +Menu 0xdd + +# evdev 128 (0x80), QKeyCode "stop", number 0xe8 +Cancel 0xe8 + +# evdev 129 (0x81), QKeyCode "again", number 0x85 +Redo 0x85 + +# evdev 130 (0x82), QKeyCode "props", number 0x86 +SunProps 0x86 + +# evdev 131 (0x83), QKeyCode "undo", number 0x87 +Undo 0x87 + +# evdev 132 (0x84), QKeyCode "front", number 0x8c +SunFront 0x8c + +# evdev 133 (0x85), QKeyCode "copy", number 0xf8 +XF86Copy 0xf8 + +# evdev 134 (0x86), QKeyCode "open", number 0x64 +XF86Open 0x64 + +# evdev 135 (0x87), QKeyCode "paste", number 0x65 +XF86Paste 0x65 + +# evdev 136 (0x88), QKeyCode "find", number 0xc1 +Find 0xc1 + +# evdev 137 (0x89), QKeyCode "cut", number 0xbc +XF86Cut 0xbc + +# evdev 138 (0x8a), QKeyCode "help", number 0xf5 +Help 0xf5 + +# evdev 139 (0x8b), QKeyCode "menu", number 0x9e +XF86MenuKB 0x9e + +# evdev 140 (0x8c), QKeyCode "calculator", number 0xa1 +XF86Calculator 0xa1 + +# evdev 141 (0x8d): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 142 (0x8e), QKeyCode "sleep", number 0xdf +XF86Sleep 0xdf + +# evdev 143 (0x8f), QKeyCode "wake", number 0xe3 +XF86WakeUp 0xe3 + +# evdev 144 (0x90): no evdev -> QKeyCode mapping (xkb keysym XF86Explorer) + +# evdev 145 (0x91): no evdev -> QKeyCode mapping (xkb keysym XF86Send) + +# evdev 146 (0x92): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 147 (0x93): no evdev -> QKeyCode mapping (xkb keysym XF86Xfer) + +# evdev 148 (0x94): no evdev -> QKeyCode mapping (xkb keysym XF86Launch1) + +# evdev 149 (0x95): no evdev -> QKeyCode mapping (xkb keysym XF86Launch2) + +# evdev 150 (0x96): no evdev -> QKeyCode mapping (xkb keysym XF86WWW) + +# evdev 151 (0x97): no evdev -> QKeyCode mapping (xkb keysym XF86DOS) + +# evdev 152 (0x98): no evdev -> QKeyCode mapping (xkb keysym XF86ScreenSaver) + +# evdev 153 (0x99): no evdev -> QKeyCode mapping (xkb keysym XF86RotateWindows) + +# evdev 154 (0x9a): no evdev -> QKeyCode mapping (xkb keysym XF86TaskPane) + +# evdev 155 (0x9b), QKeyCode "mail", number 0xec +XF86Mail 0xec + +# evdev 156 (0x9c), QKeyCode "ac_bookmarks", number 0xe6 +XF86Favorites 0xe6 + +# evdev 157 (0x9d), QKeyCode "computer", number 0xeb +XF86MyComputer 0xeb + +# evdev 158 (0x9e), QKeyCode "ac_back", number 0xea +XF86Back 0xea + +# evdev 159 (0x9f), QKeyCode "ac_forward", number 0xe9 +XF86Forward 0xe9 + +# evdev 160 (0xa0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 161 (0xa1): no evdev -> QKeyCode mapping (xkb keysym XF86Eject) + +# evdev 162 (0xa2): no evdev -> QKeyCode mapping (xkb keysym XF86Eject) + +# evdev 163 (0xa3), QKeyCode "audionext", number 0x99 +XF86AudioNext 0x99 + +# evdev 164 (0xa4), QKeyCode "audioplay", number 0xa2 +XF86AudioPlay 0xa2 +XF86AudioPause 0xa2 shift + +# evdev 165 (0xa5), QKeyCode "audioprev", number 0x90 +XF86AudioPrev 0x90 + +# evdev 166 (0xa6), QKeyCode "audiostop", number 0xa4 +XF86AudioStop 0xa4 +XF86Eject 0xa4 shift + +# evdev 167 (0xa7): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRecord) + +# evdev 168 (0xa8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRewind) + +# evdev 169 (0xa9): no evdev -> QKeyCode mapping (xkb keysym XF86Phone) + +# evdev 170 (0xaa): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 171 (0xab): no evdev -> QKeyCode mapping (xkb keysym XF86Tools) + +# evdev 172 (0xac), QKeyCode "ac_home", number 0xb2 +XF86HomePage 0xb2 + +# evdev 173 (0xad), QKeyCode "ac_refresh", number 0xe7 +XF86Reload 0xe7 + +# evdev 174 (0xae): no evdev -> QKeyCode mapping (xkb keysym XF86Close) + +# evdev 175 (0xaf): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 176 (0xb0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 177 (0xb1): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollUp) + +# evdev 178 (0xb2): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollDown) + +# evdev 179 (0xb3): no evdev -> QKeyCode mapping (xkb keysym parenleft) + +# evdev 180 (0xb4): no evdev -> QKeyCode mapping (xkb keysym parenright) + +# evdev 181 (0xb5): no evdev -> QKeyCode mapping (xkb keysym XF86New) + +# evdev 182 (0xb6): no evdev -> QKeyCode mapping (xkb keysym Redo) + +# evdev 183 (0xb7): no evdev -> QKeyCode mapping (xkb keysym XF86Tools) + +# evdev 184 (0xb8): no evdev -> QKeyCode mapping (xkb keysym XF86Launch5) + +# evdev 185 (0xb9): no evdev -> QKeyCode mapping (xkb keysym XF86Launch6) + +# evdev 186 (0xba): no evdev -> QKeyCode mapping (xkb keysym XF86Launch7) + +# evdev 187 (0xbb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch8) + +# evdev 188 (0xbc): no evdev -> QKeyCode mapping (xkb keysym XF86Launch9) + +# evdev 189 (0xbd): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 190 (0xbe): no evdev -> QKeyCode mapping (xkb keysym XF86AudioMicMute) + +# evdev 191 (0xbf): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadToggle) + +# evdev 192 (0xc0): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOn) + +# evdev 193 (0xc1): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOff) + +# evdev 194 (0xc2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 195 (0xc3): no evdev -> QKeyCode mapping (xkb keysym Mode_switch) + +# evdev 196 (0xc4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 197 (0xc5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 198 (0xc6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 199 (0xc7): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 200 (0xc8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay) + +# evdev 201 (0xc9): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPause) + +# evdev 202 (0xca): no evdev -> QKeyCode mapping (xkb keysym XF86Launch3) + +# evdev 203 (0xcb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch4) + +# evdev 204 (0xcc): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchB) + +# evdev 205 (0xcd): no evdev -> QKeyCode mapping (xkb keysym XF86Suspend) + +# evdev 206 (0xce): no evdev -> QKeyCode mapping (xkb keysym XF86Close) + +# evdev 207 (0xcf): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay) + +# evdev 208 (0xd0): no evdev -> QKeyCode mapping (xkb keysym XF86AudioForward) + +# evdev 209 (0xd1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 210 (0xd2): no evdev -> QKeyCode mapping (xkb keysym Print) + +# evdev 211 (0xd3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 212 (0xd4): no evdev -> QKeyCode mapping (xkb keysym XF86WebCam) + +# evdev 213 (0xd5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 214 (0xd6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 215 (0xd7): no evdev -> QKeyCode mapping (xkb keysym XF86Mail) + +# evdev 216 (0xd8): no evdev -> QKeyCode mapping (xkb keysym XF86Messenger) + +# evdev 217 (0xd9): no evdev -> QKeyCode mapping (xkb keysym XF86Search) + +# evdev 218 (0xda): no evdev -> QKeyCode mapping (xkb keysym XF86Go) + +# evdev 219 (0xdb): no evdev -> QKeyCode mapping (xkb keysym XF86Finance) + +# evdev 220 (0xdc): no evdev -> QKeyCode mapping (xkb keysym XF86Game) + +# evdev 221 (0xdd): no evdev -> QKeyCode mapping (xkb keysym XF86Shop) + +# evdev 222 (0xde): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 223 (0xdf): no evdev -> QKeyCode mapping (xkb keysym Cancel) + +# evdev 224 (0xe0): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessDown) + +# evdev 225 (0xe1): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessUp) + +# evdev 226 (0xe2), QKeyCode "mediaselect", number 0xed +XF86AudioMedia 0xed + +# evdev 227 (0xe3): no evdev -> QKeyCode mapping (xkb keysym XF86Display) + +# evdev 228 (0xe4): no evdev -> QKeyCode mapping (xkb keysym XF86KbdLightOnOff) + +# evdev 229 (0xe5): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessDown) + +# evdev 230 (0xe6): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessUp) + +# evdev 231 (0xe7): no evdev -> QKeyCode mapping (xkb keysym XF86Send) + +# evdev 232 (0xe8): no evdev -> QKeyCode mapping (xkb keysym XF86Reply) + +# evdev 233 (0xe9): no evdev -> QKeyCode mapping (xkb keysym XF86MailForward) + +# evdev 234 (0xea): no evdev -> QKeyCode mapping (xkb keysym XF86Save) + +# evdev 235 (0xeb): no evdev -> QKeyCode mapping (xkb keysym XF86Documents) + +# evdev 236 (0xec): no evdev -> QKeyCode mapping (xkb keysym XF86Battery) + +# evdev 237 (0xed): no evdev -> QKeyCode mapping (xkb keysym XF86Bluetooth) + +# evdev 238 (0xee): no evdev -> QKeyCode mapping (xkb keysym XF86WLAN) + +# evdev 239 (0xef): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 240 (0xf0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 241 (0xf1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 242 (0xf2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 243 (0xf3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 244 (0xf4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 245 (0xf5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 246 (0xf6): no evdev -> QKeyCode mapping (xkb keysym Invalid) + +# evdev 247 (0xf7): no evdev -> QKeyCode mapping (xkb keysym Invalid) + +# +# quirks section start +# +# Sometimes multiple keysyms map to the same keycodes. +# The keycode -> keysym lookup finds only one of the +# keysyms. So append them here. +# + +Print 0x54 +Sys_Req 0x54 +Execute 0x54 +KP_Decimal 0x53 numlock +KP_Separator 0x53 numlock +Alt_R 0xb8 +ISO_Level3_Shift 0xb8 +Mode_switch 0xb8 + +# quirks section end diff --git a/app/src/main/assets/roms/keymaps/en-gb b/app/src/main/assets/roms/keymaps/en-gb new file mode 100644 index 0000000..18d8fce --- /dev/null +++ b/app/src/main/assets/roms/keymaps/en-gb @@ -0,0 +1,841 @@ +# +# generated by qemu-keymap +# model : pc105 +# layout : gb +# variant : - +# options : - + +# name: "English (UK)" + +# modifiers +# 0: Shift +# 1: Lock +# 2: Control +# 3: Mod1 +# 4: Mod2 +# 5: Mod3 +# 6: Mod4 +# 7: Mod5 +# 8: NumLock +# 9: Alt +# 10: LevelThree +# 11: LAlt +# 12: RAlt +# 13: RControl +# 14: LControl +# 15: ScrollLock +# 16: LevelFive +# 17: AltGr +# 18: Meta +# 19: Super +# 20: Hyper + +# evdev 1 (0x1), QKeyCode "esc", number 0x1 +Escape 0x01 + +# evdev 2 (0x2), QKeyCode "1", number 0x2 +1 0x02 +exclam 0x02 shift +onesuperior 0x02 altgr +exclamdown 0x02 shift altgr + +# evdev 3 (0x3), QKeyCode "2", number 0x3 +2 0x03 +quotedbl 0x03 shift +twosuperior 0x03 altgr +oneeighth 0x03 shift altgr + +# evdev 4 (0x4), QKeyCode "3", number 0x4 +3 0x04 +sterling 0x04 shift +threesuperior 0x04 altgr + +# evdev 5 (0x5), QKeyCode "4", number 0x5 +4 0x05 +dollar 0x05 shift +EuroSign 0x05 altgr +onequarter 0x05 shift altgr + +# evdev 6 (0x6), QKeyCode "5", number 0x6 +5 0x06 +percent 0x06 shift +onehalf 0x06 altgr +threeeighths 0x06 shift altgr + +# evdev 7 (0x7), QKeyCode "6", number 0x7 +6 0x07 +asciicircum 0x07 shift +threequarters 0x07 altgr +fiveeighths 0x07 shift altgr + +# evdev 8 (0x8), QKeyCode "7", number 0x8 +7 0x08 +ampersand 0x08 shift +braceleft 0x08 altgr +seveneighths 0x08 shift altgr + +# evdev 9 (0x9), QKeyCode "8", number 0x9 +8 0x09 +asterisk 0x09 shift +bracketleft 0x09 altgr +trademark 0x09 shift altgr + +# evdev 10 (0xa), QKeyCode "9", number 0xa +9 0x0a +parenleft 0x0a shift +bracketright 0x0a altgr +plusminus 0x0a shift altgr + +# evdev 11 (0xb), QKeyCode "0", number 0xb +0 0x0b +parenright 0x0b shift +braceright 0x0b altgr +degree 0x0b shift altgr + +# evdev 12 (0xc), QKeyCode "minus", number 0xc +minus 0x0c +underscore 0x0c shift +backslash 0x0c altgr +questiondown 0x0c shift altgr + +# evdev 13 (0xd), QKeyCode "equal", number 0xd +equal 0x0d +plus 0x0d shift +dead_cedilla 0x0d altgr +dead_ogonek 0x0d shift altgr + +# evdev 14 (0xe), QKeyCode "backspace", number 0xe +BackSpace 0x0e + +# evdev 15 (0xf), QKeyCode "tab", number 0xf +Tab 0x0f +ISO_Left_Tab 0x0f shift + +# evdev 16 (0x10), QKeyCode "q", number 0x10 +q 0x10 +Q 0x10 shift +at 0x10 altgr +Greek_OMEGA 0x10 shift altgr + +# evdev 17 (0x11), QKeyCode "w", number 0x11 +w 0x11 +W 0x11 shift +lstroke 0x11 altgr +Lstroke 0x11 shift altgr + +# evdev 18 (0x12), QKeyCode "e", number 0x12 +e 0x12 +E 0x12 shift + +# evdev 19 (0x13), QKeyCode "r", number 0x13 +r 0x13 +R 0x13 shift +paragraph 0x13 altgr +registered 0x13 shift altgr + +# evdev 20 (0x14), QKeyCode "t", number 0x14 +t 0x14 +T 0x14 shift +tslash 0x14 altgr +Tslash 0x14 shift altgr + +# evdev 21 (0x15), QKeyCode "y", number 0x15 +y 0x15 +Y 0x15 shift +leftarrow 0x15 altgr +yen 0x15 shift altgr + +# evdev 22 (0x16), QKeyCode "u", number 0x16 +u 0x16 +U 0x16 shift +downarrow 0x16 altgr +uparrow 0x16 shift altgr + +# evdev 23 (0x17), QKeyCode "i", number 0x17 +i 0x17 +I 0x17 shift +rightarrow 0x17 altgr +idotless 0x17 shift altgr + +# evdev 24 (0x18), QKeyCode "o", number 0x18 +o 0x18 +O 0x18 shift +oslash 0x18 altgr +Oslash 0x18 shift altgr + +# evdev 25 (0x19), QKeyCode "p", number 0x19 +p 0x19 +P 0x19 shift +thorn 0x19 altgr +THORN 0x19 shift altgr + +# evdev 26 (0x1a), QKeyCode "bracket_left", number 0x1a +bracketleft 0x1a +braceleft 0x1a shift +dead_diaeresis 0x1a altgr +dead_abovering 0x1a shift altgr + +# evdev 27 (0x1b), QKeyCode "bracket_right", number 0x1b +bracketright 0x1b +braceright 0x1b shift +dead_tilde 0x1b altgr +dead_macron 0x1b shift altgr + +# evdev 28 (0x1c), QKeyCode "ret", number 0x1c +Return 0x1c + +# evdev 29 (0x1d), QKeyCode "ctrl", number 0x1d +Control_L 0x1d + +# evdev 30 (0x1e), QKeyCode "a", number 0x1e +a 0x1e +A 0x1e shift +ae 0x1e altgr +AE 0x1e shift altgr + +# evdev 31 (0x1f), QKeyCode "s", number 0x1f +s 0x1f +S 0x1f shift +ssharp 0x1f altgr +section 0x1f shift altgr + +# evdev 32 (0x20), QKeyCode "d", number 0x20 +d 0x20 +D 0x20 shift +eth 0x20 altgr +ETH 0x20 shift altgr + +# evdev 33 (0x21), QKeyCode "f", number 0x21 +f 0x21 +F 0x21 shift +dstroke 0x21 altgr +ordfeminine 0x21 shift altgr + +# evdev 34 (0x22), QKeyCode "g", number 0x22 +g 0x22 +G 0x22 shift +eng 0x22 altgr +ENG 0x22 shift altgr + +# evdev 35 (0x23), QKeyCode "h", number 0x23 +h 0x23 +H 0x23 shift +hstroke 0x23 altgr +Hstroke 0x23 shift altgr + +# evdev 36 (0x24), QKeyCode "j", number 0x24 +j 0x24 +J 0x24 shift +dead_hook 0x24 altgr +dead_horn 0x24 shift altgr + +# evdev 37 (0x25), QKeyCode "k", number 0x25 +k 0x25 +K 0x25 shift +kra 0x25 altgr +ampersand 0x25 shift altgr + +# evdev 38 (0x26), QKeyCode "l", number 0x26 +l 0x26 +L 0x26 shift +lstroke 0x26 altgr +Lstroke 0x26 shift altgr + +# evdev 39 (0x27), QKeyCode "semicolon", number 0x27 +semicolon 0x27 +colon 0x27 shift +dead_acute 0x27 altgr +dead_doubleacute 0x27 shift altgr + +# evdev 40 (0x28), QKeyCode "apostrophe", number 0x28 +apostrophe 0x28 +at 0x28 shift +dead_circumflex 0x28 altgr +dead_caron 0x28 shift altgr + +# evdev 41 (0x29), QKeyCode "grave_accent", number 0x29 +grave 0x29 +notsign 0x29 shift +bar 0x29 altgr + +# evdev 42 (0x2a), QKeyCode "shift", number 0x2a +Shift_L 0x2a + +# evdev 43 (0x2b), QKeyCode "backslash", number 0x2b +numbersign 0x2b +asciitilde 0x2b shift +dead_grave 0x2b altgr +dead_breve 0x2b shift altgr + +# evdev 44 (0x2c), QKeyCode "z", number 0x2c +z 0x2c +Z 0x2c shift +guillemotleft 0x2c altgr +less 0x2c shift altgr + +# evdev 45 (0x2d), QKeyCode "x", number 0x2d +x 0x2d +X 0x2d shift +guillemotright 0x2d altgr +greater 0x2d shift altgr + +# evdev 46 (0x2e), QKeyCode "c", number 0x2e +c 0x2e +C 0x2e shift +cent 0x2e altgr +copyright 0x2e shift altgr + +# evdev 47 (0x2f), QKeyCode "v", number 0x2f +v 0x2f +V 0x2f shift +leftdoublequotemark 0x2f altgr +leftsinglequotemark 0x2f shift altgr + +# evdev 48 (0x30), QKeyCode "b", number 0x30 +b 0x30 +B 0x30 shift +rightdoublequotemark 0x30 altgr +rightsinglequotemark 0x30 shift altgr + +# evdev 49 (0x31), QKeyCode "n", number 0x31 +n 0x31 +N 0x31 shift + +# evdev 50 (0x32), QKeyCode "m", number 0x32 +m 0x32 +M 0x32 shift +mu 0x32 altgr +masculine 0x32 shift altgr + +# evdev 51 (0x33), QKeyCode "comma", number 0x33 +comma 0x33 +less 0x33 shift +horizconnector 0x33 altgr +multiply 0x33 shift altgr + +# evdev 52 (0x34), QKeyCode "dot", number 0x34 +period 0x34 +greater 0x34 shift +periodcentered 0x34 altgr +division 0x34 shift altgr + +# evdev 53 (0x35), QKeyCode "slash", number 0x35 +slash 0x35 +question 0x35 shift +dead_belowdot 0x35 altgr +dead_abovedot 0x35 shift altgr + +# evdev 54 (0x36), QKeyCode "shift_r", number 0x36 +Shift_R 0x36 + +# evdev 55 (0x37), QKeyCode "kp_multiply", number 0x37 +KP_Multiply 0x37 + +# evdev 56 (0x38), QKeyCode "alt", number 0x38 +Alt_L 0x38 +Meta_L 0x38 shift + +# evdev 57 (0x39), QKeyCode "spc", number 0x39 +space 0x39 + +# evdev 58 (0x3a), QKeyCode "caps_lock", number 0x3a +Caps_Lock 0x3a + +# evdev 59 (0x3b), QKeyCode "f1", number 0x3b +F1 0x3b + +# evdev 60 (0x3c), QKeyCode "f2", number 0x3c +F2 0x3c + +# evdev 61 (0x3d), QKeyCode "f3", number 0x3d +F3 0x3d + +# evdev 62 (0x3e), QKeyCode "f4", number 0x3e +F4 0x3e + +# evdev 63 (0x3f), QKeyCode "f5", number 0x3f +F5 0x3f + +# evdev 64 (0x40), QKeyCode "f6", number 0x40 +F6 0x40 + +# evdev 65 (0x41), QKeyCode "f7", number 0x41 +F7 0x41 + +# evdev 66 (0x42), QKeyCode "f8", number 0x42 +F8 0x42 + +# evdev 67 (0x43), QKeyCode "f9", number 0x43 +F9 0x43 + +# evdev 68 (0x44), QKeyCode "f10", number 0x44 +F10 0x44 + +# evdev 69 (0x45), QKeyCode "num_lock", number 0x45 +Num_Lock 0x45 + +# evdev 70 (0x46), QKeyCode "scroll_lock", number 0x46 +Scroll_Lock 0x46 + +# evdev 71 (0x47), QKeyCode "kp_7", number 0x47 +KP_Home 0x47 +KP_7 0x47 numlock + +# evdev 72 (0x48), QKeyCode "kp_8", number 0x48 +KP_Up 0x48 +KP_8 0x48 numlock + +# evdev 73 (0x49), QKeyCode "kp_9", number 0x49 +KP_Prior 0x49 +KP_9 0x49 numlock + +# evdev 74 (0x4a), QKeyCode "kp_subtract", number 0x4a +KP_Subtract 0x4a + +# evdev 75 (0x4b), QKeyCode "kp_4", number 0x4b +KP_Left 0x4b +KP_4 0x4b numlock + +# evdev 76 (0x4c), QKeyCode "kp_5", number 0x4c +KP_Begin 0x4c +KP_5 0x4c numlock + +# evdev 77 (0x4d), QKeyCode "kp_6", number 0x4d +KP_Right 0x4d +KP_6 0x4d numlock + +# evdev 78 (0x4e), QKeyCode "kp_add", number 0x4e +KP_Add 0x4e + +# evdev 79 (0x4f), QKeyCode "kp_1", number 0x4f +KP_End 0x4f +KP_1 0x4f numlock + +# evdev 80 (0x50), QKeyCode "kp_2", number 0x50 +KP_Down 0x50 +KP_2 0x50 numlock + +# evdev 81 (0x51), QKeyCode "kp_3", number 0x51 +KP_Next 0x51 +KP_3 0x51 numlock + +# evdev 82 (0x52), QKeyCode "kp_0", number 0x52 +KP_Insert 0x52 +KP_0 0x52 numlock + +# evdev 83 (0x53), QKeyCode "kp_decimal", number 0x53 +KP_Delete 0x53 +KP_Decimal 0x53 numlock + +# evdev 84 (0x54): no evdev -> QKeyCode mapping (xkb keysym ISO_Level3_Shift) + +# evdev 85 (0x55): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 86 (0x56), QKeyCode "less", number 0x56 +backslash 0x56 +bar 0x56 shift +bar 0x56 altgr +brokenbar 0x56 shift altgr + +# evdev 87 (0x57), QKeyCode "f11", number 0x57 +F11 0x57 + +# evdev 88 (0x58), QKeyCode "f12", number 0x58 +F12 0x58 + +# evdev 89 (0x59), QKeyCode "ro", number 0x73 + +# evdev 90 (0x5a): no evdev -> QKeyCode mapping (xkb keysym Katakana) + +# evdev 91 (0x5b), QKeyCode "hiragana", number 0x77 +Hiragana 0x77 + +# evdev 92 (0x5c), QKeyCode "henkan", number 0x79 +Henkan_Mode 0x79 + +# evdev 93 (0x5d), QKeyCode "katakanahiragana", number 0x70 +Hiragana_Katakana 0x70 + +# evdev 94 (0x5e), QKeyCode "muhenkan", number 0x7b +Muhenkan 0x7b + +# evdev 95 (0x5f): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 96 (0x60), QKeyCode "kp_enter", number 0x9c +KP_Enter 0x9c + +# evdev 97 (0x61), QKeyCode "ctrl_r", number 0x9d +Control_R 0x9d + +# evdev 98 (0x62), QKeyCode "kp_divide", number 0xb5 +KP_Divide 0xb5 + +# evdev 99 (0x63), QKeyCode "sysrq", number 0x54 +Print 0x54 + +# evdev 100 (0x64), QKeyCode "alt_r", number 0xb8 +ISO_Level3_Shift 0xb8 +Multi_key 0xb8 shift + +# evdev 101 (0x65), QKeyCode "lf", number 0x5b +Linefeed 0x5b + +# evdev 102 (0x66), QKeyCode "home", number 0xc7 +Home 0xc7 + +# evdev 103 (0x67), QKeyCode "up", number 0xc8 +Up 0xc8 + +# evdev 104 (0x68), QKeyCode "pgup", number 0xc9 +Prior 0xc9 + +# evdev 105 (0x69), QKeyCode "left", number 0xcb +Left 0xcb + +# evdev 106 (0x6a), QKeyCode "right", number 0xcd +Right 0xcd + +# evdev 107 (0x6b), QKeyCode "end", number 0xcf +End 0xcf + +# evdev 108 (0x6c), QKeyCode "down", number 0xd0 +Down 0xd0 + +# evdev 109 (0x6d), QKeyCode "pgdn", number 0xd1 +Next 0xd1 + +# evdev 110 (0x6e), QKeyCode "insert", number 0xd2 +Insert 0xd2 + +# evdev 111 (0x6f), QKeyCode "delete", number 0xd3 +Delete 0xd3 + +# evdev 112 (0x70): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 113 (0x71), QKeyCode "audiomute", number 0xa0 +XF86AudioMute 0xa0 + +# evdev 114 (0x72), QKeyCode "volumedown", number 0xae +XF86AudioLowerVolume 0xae + +# evdev 115 (0x73), QKeyCode "volumeup", number 0xb0 +XF86AudioRaiseVolume 0xb0 + +# evdev 116 (0x74), QKeyCode "power", number 0xde +XF86PowerOff 0xde + +# evdev 117 (0x75), QKeyCode "kp_equals", number 0x59 +KP_Equal 0x59 + +# evdev 118 (0x76): no evdev -> QKeyCode mapping (xkb keysym plusminus) + +# evdev 119 (0x77), QKeyCode "pause", number 0xc6 +Pause 0xc6 + +# evdev 120 (0x78): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchA) + +# evdev 121 (0x79), QKeyCode "kp_comma", number 0x7e +KP_Decimal 0x7e + +# evdev 122 (0x7a): no evdev -> QKeyCode mapping (xkb keysym Hangul) + +# evdev 123 (0x7b): no evdev -> QKeyCode mapping (xkb keysym Hangul_Hanja) + +# evdev 124 (0x7c), QKeyCode "yen", number 0x7d + +# evdev 125 (0x7d), QKeyCode "meta_l", number 0xdb +Super_L 0xdb + +# evdev 126 (0x7e), QKeyCode "meta_r", number 0xdc +Super_R 0xdc + +# evdev 127 (0x7f), QKeyCode "compose", number 0xdd +Menu 0xdd + +# evdev 128 (0x80), QKeyCode "stop", number 0xe8 +Cancel 0xe8 + +# evdev 129 (0x81), QKeyCode "again", number 0x85 +Redo 0x85 + +# evdev 130 (0x82), QKeyCode "props", number 0x86 +SunProps 0x86 + +# evdev 131 (0x83), QKeyCode "undo", number 0x87 +Undo 0x87 + +# evdev 132 (0x84), QKeyCode "front", number 0x8c +SunFront 0x8c + +# evdev 133 (0x85), QKeyCode "copy", number 0xf8 +XF86Copy 0xf8 + +# evdev 134 (0x86), QKeyCode "open", number 0x64 +XF86Open 0x64 + +# evdev 135 (0x87), QKeyCode "paste", number 0x65 +XF86Paste 0x65 + +# evdev 136 (0x88), QKeyCode "find", number 0xc1 +Find 0xc1 + +# evdev 137 (0x89), QKeyCode "cut", number 0xbc +XF86Cut 0xbc + +# evdev 138 (0x8a), QKeyCode "help", number 0xf5 +Help 0xf5 + +# evdev 139 (0x8b), QKeyCode "menu", number 0x9e +XF86MenuKB 0x9e + +# evdev 140 (0x8c), QKeyCode "calculator", number 0xa1 +XF86Calculator 0xa1 + +# evdev 141 (0x8d): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 142 (0x8e), QKeyCode "sleep", number 0xdf +XF86Sleep 0xdf + +# evdev 143 (0x8f), QKeyCode "wake", number 0xe3 +XF86WakeUp 0xe3 + +# evdev 144 (0x90): no evdev -> QKeyCode mapping (xkb keysym XF86Explorer) + +# evdev 145 (0x91): no evdev -> QKeyCode mapping (xkb keysym XF86Send) + +# evdev 146 (0x92): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 147 (0x93): no evdev -> QKeyCode mapping (xkb keysym XF86Xfer) + +# evdev 148 (0x94): no evdev -> QKeyCode mapping (xkb keysym XF86Launch1) + +# evdev 149 (0x95): no evdev -> QKeyCode mapping (xkb keysym XF86Launch2) + +# evdev 150 (0x96): no evdev -> QKeyCode mapping (xkb keysym XF86WWW) + +# evdev 151 (0x97): no evdev -> QKeyCode mapping (xkb keysym XF86DOS) + +# evdev 152 (0x98): no evdev -> QKeyCode mapping (xkb keysym XF86ScreenSaver) + +# evdev 153 (0x99): no evdev -> QKeyCode mapping (xkb keysym XF86RotateWindows) + +# evdev 154 (0x9a): no evdev -> QKeyCode mapping (xkb keysym XF86TaskPane) + +# evdev 155 (0x9b), QKeyCode "mail", number 0xec +XF86Mail 0xec + +# evdev 156 (0x9c), QKeyCode "ac_bookmarks", number 0xe6 +XF86Favorites 0xe6 + +# evdev 157 (0x9d), QKeyCode "computer", number 0xeb +XF86MyComputer 0xeb + +# evdev 158 (0x9e), QKeyCode "ac_back", number 0xea +XF86Back 0xea + +# evdev 159 (0x9f), QKeyCode "ac_forward", number 0xe9 +XF86Forward 0xe9 + +# evdev 160 (0xa0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 161 (0xa1): no evdev -> QKeyCode mapping (xkb keysym XF86Eject) + +# evdev 162 (0xa2): no evdev -> QKeyCode mapping (xkb keysym XF86Eject) + +# evdev 163 (0xa3), QKeyCode "audionext", number 0x99 +XF86AudioNext 0x99 + +# evdev 164 (0xa4), QKeyCode "audioplay", number 0xa2 +XF86AudioPlay 0xa2 +XF86AudioPause 0xa2 shift + +# evdev 165 (0xa5), QKeyCode "audioprev", number 0x90 +XF86AudioPrev 0x90 + +# evdev 166 (0xa6), QKeyCode "audiostop", number 0xa4 +XF86AudioStop 0xa4 +XF86Eject 0xa4 shift + +# evdev 167 (0xa7): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRecord) + +# evdev 168 (0xa8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRewind) + +# evdev 169 (0xa9): no evdev -> QKeyCode mapping (xkb keysym XF86Phone) + +# evdev 170 (0xaa): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 171 (0xab): no evdev -> QKeyCode mapping (xkb keysym XF86Tools) + +# evdev 172 (0xac), QKeyCode "ac_home", number 0xb2 +XF86HomePage 0xb2 + +# evdev 173 (0xad), QKeyCode "ac_refresh", number 0xe7 +XF86Reload 0xe7 + +# evdev 174 (0xae): no evdev -> QKeyCode mapping (xkb keysym XF86Close) + +# evdev 175 (0xaf): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 176 (0xb0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 177 (0xb1): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollUp) + +# evdev 178 (0xb2): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollDown) + +# evdev 179 (0xb3): no evdev -> QKeyCode mapping (xkb keysym parenleft) + +# evdev 180 (0xb4): no evdev -> QKeyCode mapping (xkb keysym parenright) + +# evdev 181 (0xb5): no evdev -> QKeyCode mapping (xkb keysym XF86New) + +# evdev 182 (0xb6): no evdev -> QKeyCode mapping (xkb keysym Redo) + +# evdev 183 (0xb7): no evdev -> QKeyCode mapping (xkb keysym XF86Tools) + +# evdev 184 (0xb8): no evdev -> QKeyCode mapping (xkb keysym XF86Launch5) + +# evdev 185 (0xb9): no evdev -> QKeyCode mapping (xkb keysym XF86Launch6) + +# evdev 186 (0xba): no evdev -> QKeyCode mapping (xkb keysym XF86Launch7) + +# evdev 187 (0xbb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch8) + +# evdev 188 (0xbc): no evdev -> QKeyCode mapping (xkb keysym XF86Launch9) + +# evdev 189 (0xbd): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 190 (0xbe): no evdev -> QKeyCode mapping (xkb keysym XF86AudioMicMute) + +# evdev 191 (0xbf): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadToggle) + +# evdev 192 (0xc0): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOn) + +# evdev 193 (0xc1): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOff) + +# evdev 194 (0xc2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 195 (0xc3): no evdev -> QKeyCode mapping (xkb keysym Mode_switch) + +# evdev 196 (0xc4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 197 (0xc5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 198 (0xc6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 199 (0xc7): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 200 (0xc8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay) + +# evdev 201 (0xc9): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPause) + +# evdev 202 (0xca): no evdev -> QKeyCode mapping (xkb keysym XF86Launch3) + +# evdev 203 (0xcb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch4) + +# evdev 204 (0xcc): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchB) + +# evdev 205 (0xcd): no evdev -> QKeyCode mapping (xkb keysym XF86Suspend) + +# evdev 206 (0xce): no evdev -> QKeyCode mapping (xkb keysym XF86Close) + +# evdev 207 (0xcf): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay) + +# evdev 208 (0xd0): no evdev -> QKeyCode mapping (xkb keysym XF86AudioForward) + +# evdev 209 (0xd1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 210 (0xd2): no evdev -> QKeyCode mapping (xkb keysym Print) + +# evdev 211 (0xd3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 212 (0xd4): no evdev -> QKeyCode mapping (xkb keysym XF86WebCam) + +# evdev 213 (0xd5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 214 (0xd6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 215 (0xd7): no evdev -> QKeyCode mapping (xkb keysym XF86Mail) + +# evdev 216 (0xd8): no evdev -> QKeyCode mapping (xkb keysym XF86Messenger) + +# evdev 217 (0xd9): no evdev -> QKeyCode mapping (xkb keysym XF86Search) + +# evdev 218 (0xda): no evdev -> QKeyCode mapping (xkb keysym XF86Go) + +# evdev 219 (0xdb): no evdev -> QKeyCode mapping (xkb keysym XF86Finance) + +# evdev 220 (0xdc): no evdev -> QKeyCode mapping (xkb keysym XF86Game) + +# evdev 221 (0xdd): no evdev -> QKeyCode mapping (xkb keysym XF86Shop) + +# evdev 222 (0xde): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 223 (0xdf): no evdev -> QKeyCode mapping (xkb keysym Cancel) + +# evdev 224 (0xe0): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessDown) + +# evdev 225 (0xe1): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessUp) + +# evdev 226 (0xe2), QKeyCode "mediaselect", number 0xed +XF86AudioMedia 0xed + +# evdev 227 (0xe3): no evdev -> QKeyCode mapping (xkb keysym XF86Display) + +# evdev 228 (0xe4): no evdev -> QKeyCode mapping (xkb keysym XF86KbdLightOnOff) + +# evdev 229 (0xe5): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessDown) + +# evdev 230 (0xe6): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessUp) + +# evdev 231 (0xe7): no evdev -> QKeyCode mapping (xkb keysym XF86Send) + +# evdev 232 (0xe8): no evdev -> QKeyCode mapping (xkb keysym XF86Reply) + +# evdev 233 (0xe9): no evdev -> QKeyCode mapping (xkb keysym XF86MailForward) + +# evdev 234 (0xea): no evdev -> QKeyCode mapping (xkb keysym XF86Save) + +# evdev 235 (0xeb): no evdev -> QKeyCode mapping (xkb keysym XF86Documents) + +# evdev 236 (0xec): no evdev -> QKeyCode mapping (xkb keysym XF86Battery) + +# evdev 237 (0xed): no evdev -> QKeyCode mapping (xkb keysym XF86Bluetooth) + +# evdev 238 (0xee): no evdev -> QKeyCode mapping (xkb keysym XF86WLAN) + +# evdev 239 (0xef): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 240 (0xf0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 241 (0xf1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 242 (0xf2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 243 (0xf3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 244 (0xf4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 245 (0xf5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 246 (0xf6): no evdev -> QKeyCode mapping (xkb keysym Invalid) + +# evdev 247 (0xf7): no evdev -> QKeyCode mapping (xkb keysym Invalid) + +# +# quirks section start +# +# Sometimes multiple keysyms map to the same keycodes. +# The keycode -> keysym lookup finds only one of the +# keysyms. So append them here. +# + +Print 0x54 +Sys_Req 0x54 +Execute 0x54 +KP_Decimal 0x53 numlock +KP_Separator 0x53 numlock +Alt_R 0xb8 +ISO_Level3_Shift 0xb8 +Mode_switch 0xb8 + +# quirks section end diff --git a/app/src/main/assets/roms/keymaps/en-us b/app/src/main/assets/roms/keymaps/en-us new file mode 100644 index 0000000..06762cf --- /dev/null +++ b/app/src/main/assets/roms/keymaps/en-us @@ -0,0 +1,753 @@ +# +# generated by qemu-keymap +# model : pc105 +# layout : us +# variant : - +# options : - + +# name: "English (US)" + +# modifiers +# 0: Shift +# 1: Lock +# 2: Control +# 3: Mod1 +# 4: Mod2 +# 5: Mod3 +# 6: Mod4 +# 7: Mod5 +# 8: NumLock +# 9: Alt +# 10: LevelThree +# 11: LAlt +# 12: RAlt +# 13: RControl +# 14: LControl +# 15: ScrollLock +# 16: LevelFive +# 17: AltGr +# 18: Meta +# 19: Super +# 20: Hyper + +# evdev 1 (0x1), QKeyCode "esc", number 0x1 +Escape 0x01 + +# evdev 2 (0x2), QKeyCode "1", number 0x2 +1 0x02 +exclam 0x02 shift + +# evdev 3 (0x3), QKeyCode "2", number 0x3 +2 0x03 +at 0x03 shift + +# evdev 4 (0x4), QKeyCode "3", number 0x4 +3 0x04 +numbersign 0x04 shift + +# evdev 5 (0x5), QKeyCode "4", number 0x5 +4 0x05 +dollar 0x05 shift + +# evdev 6 (0x6), QKeyCode "5", number 0x6 +5 0x06 +percent 0x06 shift + +# evdev 7 (0x7), QKeyCode "6", number 0x7 +6 0x07 +asciicircum 0x07 shift + +# evdev 8 (0x8), QKeyCode "7", number 0x8 +7 0x08 +ampersand 0x08 shift + +# evdev 9 (0x9), QKeyCode "8", number 0x9 +8 0x09 +asterisk 0x09 shift + +# evdev 10 (0xa), QKeyCode "9", number 0xa +9 0x0a +parenleft 0x0a shift + +# evdev 11 (0xb), QKeyCode "0", number 0xb +0 0x0b +parenright 0x0b shift + +# evdev 12 (0xc), QKeyCode "minus", number 0xc +minus 0x0c +underscore 0x0c shift + +# evdev 13 (0xd), QKeyCode "equal", number 0xd +equal 0x0d +plus 0x0d shift + +# evdev 14 (0xe), QKeyCode "backspace", number 0xe +BackSpace 0x0e + +# evdev 15 (0xf), QKeyCode "tab", number 0xf +Tab 0x0f +ISO_Left_Tab 0x0f shift + +# evdev 16 (0x10), QKeyCode "q", number 0x10 +q 0x10 +Q 0x10 shift + +# evdev 17 (0x11), QKeyCode "w", number 0x11 +w 0x11 +W 0x11 shift + +# evdev 18 (0x12), QKeyCode "e", number 0x12 +e 0x12 +E 0x12 shift + +# evdev 19 (0x13), QKeyCode "r", number 0x13 +r 0x13 +R 0x13 shift + +# evdev 20 (0x14), QKeyCode "t", number 0x14 +t 0x14 +T 0x14 shift + +# evdev 21 (0x15), QKeyCode "y", number 0x15 +y 0x15 +Y 0x15 shift + +# evdev 22 (0x16), QKeyCode "u", number 0x16 +u 0x16 +U 0x16 shift + +# evdev 23 (0x17), QKeyCode "i", number 0x17 +i 0x17 +I 0x17 shift + +# evdev 24 (0x18), QKeyCode "o", number 0x18 +o 0x18 +O 0x18 shift + +# evdev 25 (0x19), QKeyCode "p", number 0x19 +p 0x19 +P 0x19 shift + +# evdev 26 (0x1a), QKeyCode "bracket_left", number 0x1a +bracketleft 0x1a +braceleft 0x1a shift + +# evdev 27 (0x1b), QKeyCode "bracket_right", number 0x1b +bracketright 0x1b +braceright 0x1b shift + +# evdev 28 (0x1c), QKeyCode "ret", number 0x1c +Return 0x1c + +# evdev 29 (0x1d), QKeyCode "ctrl", number 0x1d +Control_L 0x1d + +# evdev 30 (0x1e), QKeyCode "a", number 0x1e +a 0x1e +A 0x1e shift + +# evdev 31 (0x1f), QKeyCode "s", number 0x1f +s 0x1f +S 0x1f shift + +# evdev 32 (0x20), QKeyCode "d", number 0x20 +d 0x20 +D 0x20 shift + +# evdev 33 (0x21), QKeyCode "f", number 0x21 +f 0x21 +F 0x21 shift + +# evdev 34 (0x22), QKeyCode "g", number 0x22 +g 0x22 +G 0x22 shift + +# evdev 35 (0x23), QKeyCode "h", number 0x23 +h 0x23 +H 0x23 shift + +# evdev 36 (0x24), QKeyCode "j", number 0x24 +j 0x24 +J 0x24 shift + +# evdev 37 (0x25), QKeyCode "k", number 0x25 +k 0x25 +K 0x25 shift + +# evdev 38 (0x26), QKeyCode "l", number 0x26 +l 0x26 +L 0x26 shift + +# evdev 39 (0x27), QKeyCode "semicolon", number 0x27 +semicolon 0x27 +colon 0x27 shift + +# evdev 40 (0x28), QKeyCode "apostrophe", number 0x28 +apostrophe 0x28 +quotedbl 0x28 shift + +# evdev 41 (0x29), QKeyCode "grave_accent", number 0x29 +grave 0x29 +asciitilde 0x29 shift + +# evdev 42 (0x2a), QKeyCode "shift", number 0x2a +Shift_L 0x2a + +# evdev 43 (0x2b), QKeyCode "backslash", number 0x2b +backslash 0x2b +bar 0x2b shift + +# evdev 44 (0x2c), QKeyCode "z", number 0x2c +z 0x2c +Z 0x2c shift + +# evdev 45 (0x2d), QKeyCode "x", number 0x2d +x 0x2d +X 0x2d shift + +# evdev 46 (0x2e), QKeyCode "c", number 0x2e +c 0x2e +C 0x2e shift + +# evdev 47 (0x2f), QKeyCode "v", number 0x2f +v 0x2f +V 0x2f shift + +# evdev 48 (0x30), QKeyCode "b", number 0x30 +b 0x30 +B 0x30 shift + +# evdev 49 (0x31), QKeyCode "n", number 0x31 +n 0x31 +N 0x31 shift + +# evdev 50 (0x32), QKeyCode "m", number 0x32 +m 0x32 +M 0x32 shift + +# evdev 51 (0x33), QKeyCode "comma", number 0x33 +comma 0x33 +less 0x33 shift + +# evdev 52 (0x34), QKeyCode "dot", number 0x34 +period 0x34 +greater 0x34 shift + +# evdev 53 (0x35), QKeyCode "slash", number 0x35 +slash 0x35 +question 0x35 shift + +# evdev 54 (0x36), QKeyCode "shift_r", number 0x36 +Shift_R 0x36 + +# evdev 55 (0x37), QKeyCode "kp_multiply", number 0x37 +KP_Multiply 0x37 + +# evdev 56 (0x38), QKeyCode "alt", number 0x38 +Alt_L 0x38 +Meta_L 0x38 shift + +# evdev 57 (0x39), QKeyCode "spc", number 0x39 +space 0x39 + +# evdev 58 (0x3a), QKeyCode "caps_lock", number 0x3a +Caps_Lock 0x3a + +# evdev 59 (0x3b), QKeyCode "f1", number 0x3b +F1 0x3b + +# evdev 60 (0x3c), QKeyCode "f2", number 0x3c +F2 0x3c + +# evdev 61 (0x3d), QKeyCode "f3", number 0x3d +F3 0x3d + +# evdev 62 (0x3e), QKeyCode "f4", number 0x3e +F4 0x3e + +# evdev 63 (0x3f), QKeyCode "f5", number 0x3f +F5 0x3f + +# evdev 64 (0x40), QKeyCode "f6", number 0x40 +F6 0x40 + +# evdev 65 (0x41), QKeyCode "f7", number 0x41 +F7 0x41 + +# evdev 66 (0x42), QKeyCode "f8", number 0x42 +F8 0x42 + +# evdev 67 (0x43), QKeyCode "f9", number 0x43 +F9 0x43 + +# evdev 68 (0x44), QKeyCode "f10", number 0x44 +F10 0x44 + +# evdev 69 (0x45), QKeyCode "num_lock", number 0x45 +Num_Lock 0x45 + +# evdev 70 (0x46), QKeyCode "scroll_lock", number 0x46 +Scroll_Lock 0x46 + +# evdev 71 (0x47), QKeyCode "kp_7", number 0x47 +KP_Home 0x47 +KP_7 0x47 numlock + +# evdev 72 (0x48), QKeyCode "kp_8", number 0x48 +KP_Up 0x48 +KP_8 0x48 numlock + +# evdev 73 (0x49), QKeyCode "kp_9", number 0x49 +KP_Prior 0x49 +KP_9 0x49 numlock + +# evdev 74 (0x4a), QKeyCode "kp_subtract", number 0x4a +KP_Subtract 0x4a + +# evdev 75 (0x4b), QKeyCode "kp_4", number 0x4b +KP_Left 0x4b +KP_4 0x4b numlock + +# evdev 76 (0x4c), QKeyCode "kp_5", number 0x4c +KP_Begin 0x4c +KP_5 0x4c numlock + +# evdev 77 (0x4d), QKeyCode "kp_6", number 0x4d +KP_Right 0x4d +KP_6 0x4d numlock + +# evdev 78 (0x4e), QKeyCode "kp_add", number 0x4e +KP_Add 0x4e + +# evdev 79 (0x4f), QKeyCode "kp_1", number 0x4f +KP_End 0x4f +KP_1 0x4f numlock + +# evdev 80 (0x50), QKeyCode "kp_2", number 0x50 +KP_Down 0x50 +KP_2 0x50 numlock + +# evdev 81 (0x51), QKeyCode "kp_3", number 0x51 +KP_Next 0x51 +KP_3 0x51 numlock + +# evdev 82 (0x52), QKeyCode "kp_0", number 0x52 +KP_Insert 0x52 +KP_0 0x52 numlock + +# evdev 83 (0x53), QKeyCode "kp_decimal", number 0x53 +KP_Delete 0x53 +KP_Decimal 0x53 numlock + +# evdev 84 (0x54): no evdev -> QKeyCode mapping (xkb keysym ISO_Level3_Shift) + +# evdev 85 (0x55): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 86 (0x56), QKeyCode "less", number 0x56 +less 0x56 +greater 0x56 shift +bar 0x56 altgr +brokenbar 0x56 shift altgr + +# evdev 87 (0x57), QKeyCode "f11", number 0x57 +F11 0x57 + +# evdev 88 (0x58), QKeyCode "f12", number 0x58 +F12 0x58 + +# evdev 89 (0x59), QKeyCode "ro", number 0x73 + +# evdev 90 (0x5a): no evdev -> QKeyCode mapping (xkb keysym Katakana) + +# evdev 91 (0x5b), QKeyCode "hiragana", number 0x77 +Hiragana 0x77 + +# evdev 92 (0x5c), QKeyCode "henkan", number 0x79 +Henkan_Mode 0x79 + +# evdev 93 (0x5d), QKeyCode "katakanahiragana", number 0x70 +Hiragana_Katakana 0x70 + +# evdev 94 (0x5e), QKeyCode "muhenkan", number 0x7b +Muhenkan 0x7b + +# evdev 95 (0x5f): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 96 (0x60), QKeyCode "kp_enter", number 0x9c +KP_Enter 0x9c + +# evdev 97 (0x61), QKeyCode "ctrl_r", number 0x9d +Control_R 0x9d + +# evdev 98 (0x62), QKeyCode "kp_divide", number 0xb5 +KP_Divide 0xb5 + +# evdev 99 (0x63), QKeyCode "sysrq", number 0x54 +Print 0x54 + +# evdev 100 (0x64), QKeyCode "alt_r", number 0xb8 +Alt_R 0xb8 +Meta_R 0xb8 shift + +# evdev 101 (0x65), QKeyCode "lf", number 0x5b +Linefeed 0x5b + +# evdev 102 (0x66), QKeyCode "home", number 0xc7 +Home 0xc7 + +# evdev 103 (0x67), QKeyCode "up", number 0xc8 +Up 0xc8 + +# evdev 104 (0x68), QKeyCode "pgup", number 0xc9 +Prior 0xc9 + +# evdev 105 (0x69), QKeyCode "left", number 0xcb +Left 0xcb + +# evdev 106 (0x6a), QKeyCode "right", number 0xcd +Right 0xcd + +# evdev 107 (0x6b), QKeyCode "end", number 0xcf +End 0xcf + +# evdev 108 (0x6c), QKeyCode "down", number 0xd0 +Down 0xd0 + +# evdev 109 (0x6d), QKeyCode "pgdn", number 0xd1 +Next 0xd1 + +# evdev 110 (0x6e), QKeyCode "insert", number 0xd2 +Insert 0xd2 + +# evdev 111 (0x6f), QKeyCode "delete", number 0xd3 +Delete 0xd3 + +# evdev 112 (0x70): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 113 (0x71), QKeyCode "audiomute", number 0xa0 +XF86AudioMute 0xa0 + +# evdev 114 (0x72), QKeyCode "volumedown", number 0xae +XF86AudioLowerVolume 0xae + +# evdev 115 (0x73), QKeyCode "volumeup", number 0xb0 +XF86AudioRaiseVolume 0xb0 + +# evdev 116 (0x74), QKeyCode "power", number 0xde +XF86PowerOff 0xde + +# evdev 117 (0x75), QKeyCode "kp_equals", number 0x59 +KP_Equal 0x59 + +# evdev 118 (0x76): no evdev -> QKeyCode mapping (xkb keysym plusminus) + +# evdev 119 (0x77), QKeyCode "pause", number 0xc6 +Pause 0xc6 + +# evdev 120 (0x78): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchA) + +# evdev 121 (0x79), QKeyCode "kp_comma", number 0x7e +KP_Decimal 0x7e + +# evdev 122 (0x7a): no evdev -> QKeyCode mapping (xkb keysym Hangul) + +# evdev 123 (0x7b): no evdev -> QKeyCode mapping (xkb keysym Hangul_Hanja) + +# evdev 124 (0x7c), QKeyCode "yen", number 0x7d + +# evdev 125 (0x7d), QKeyCode "meta_l", number 0xdb +Super_L 0xdb + +# evdev 126 (0x7e), QKeyCode "meta_r", number 0xdc +Super_R 0xdc + +# evdev 127 (0x7f), QKeyCode "compose", number 0xdd +Menu 0xdd + +# evdev 128 (0x80), QKeyCode "stop", number 0xe8 +Cancel 0xe8 + +# evdev 129 (0x81), QKeyCode "again", number 0x85 +Redo 0x85 + +# evdev 130 (0x82), QKeyCode "props", number 0x86 +SunProps 0x86 + +# evdev 131 (0x83), QKeyCode "undo", number 0x87 +Undo 0x87 + +# evdev 132 (0x84), QKeyCode "front", number 0x8c +SunFront 0x8c + +# evdev 133 (0x85), QKeyCode "copy", number 0xf8 +XF86Copy 0xf8 + +# evdev 134 (0x86), QKeyCode "open", number 0x64 +XF86Open 0x64 + +# evdev 135 (0x87), QKeyCode "paste", number 0x65 +XF86Paste 0x65 + +# evdev 136 (0x88), QKeyCode "find", number 0xc1 +Find 0xc1 + +# evdev 137 (0x89), QKeyCode "cut", number 0xbc +XF86Cut 0xbc + +# evdev 138 (0x8a), QKeyCode "help", number 0xf5 +Help 0xf5 + +# evdev 139 (0x8b), QKeyCode "menu", number 0x9e +XF86MenuKB 0x9e + +# evdev 140 (0x8c), QKeyCode "calculator", number 0xa1 +XF86Calculator 0xa1 + +# evdev 141 (0x8d): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 142 (0x8e), QKeyCode "sleep", number 0xdf +XF86Sleep 0xdf + +# evdev 143 (0x8f), QKeyCode "wake", number 0xe3 +XF86WakeUp 0xe3 + +# evdev 144 (0x90): no evdev -> QKeyCode mapping (xkb keysym XF86Explorer) + +# evdev 145 (0x91): no evdev -> QKeyCode mapping (xkb keysym XF86Send) + +# evdev 146 (0x92): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 147 (0x93): no evdev -> QKeyCode mapping (xkb keysym XF86Xfer) + +# evdev 148 (0x94): no evdev -> QKeyCode mapping (xkb keysym XF86Launch1) + +# evdev 149 (0x95): no evdev -> QKeyCode mapping (xkb keysym XF86Launch2) + +# evdev 150 (0x96): no evdev -> QKeyCode mapping (xkb keysym XF86WWW) + +# evdev 151 (0x97): no evdev -> QKeyCode mapping (xkb keysym XF86DOS) + +# evdev 152 (0x98): no evdev -> QKeyCode mapping (xkb keysym XF86ScreenSaver) + +# evdev 153 (0x99): no evdev -> QKeyCode mapping (xkb keysym XF86RotateWindows) + +# evdev 154 (0x9a): no evdev -> QKeyCode mapping (xkb keysym XF86TaskPane) + +# evdev 155 (0x9b), QKeyCode "mail", number 0xec +XF86Mail 0xec + +# evdev 156 (0x9c), QKeyCode "ac_bookmarks", number 0xe6 +XF86Favorites 0xe6 + +# evdev 157 (0x9d), QKeyCode "computer", number 0xeb +XF86MyComputer 0xeb + +# evdev 158 (0x9e), QKeyCode "ac_back", number 0xea +XF86Back 0xea + +# evdev 159 (0x9f), QKeyCode "ac_forward", number 0xe9 +XF86Forward 0xe9 + +# evdev 160 (0xa0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 161 (0xa1): no evdev -> QKeyCode mapping (xkb keysym XF86Eject) + +# evdev 162 (0xa2): no evdev -> QKeyCode mapping (xkb keysym XF86Eject) + +# evdev 163 (0xa3), QKeyCode "audionext", number 0x99 +XF86AudioNext 0x99 + +# evdev 164 (0xa4), QKeyCode "audioplay", number 0xa2 +XF86AudioPlay 0xa2 +XF86AudioPause 0xa2 shift + +# evdev 165 (0xa5), QKeyCode "audioprev", number 0x90 +XF86AudioPrev 0x90 + +# evdev 166 (0xa6), QKeyCode "audiostop", number 0xa4 +XF86AudioStop 0xa4 +XF86Eject 0xa4 shift + +# evdev 167 (0xa7): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRecord) + +# evdev 168 (0xa8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRewind) + +# evdev 169 (0xa9): no evdev -> QKeyCode mapping (xkb keysym XF86Phone) + +# evdev 170 (0xaa): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 171 (0xab): no evdev -> QKeyCode mapping (xkb keysym XF86Tools) + +# evdev 172 (0xac), QKeyCode "ac_home", number 0xb2 +XF86HomePage 0xb2 + +# evdev 173 (0xad), QKeyCode "ac_refresh", number 0xe7 +XF86Reload 0xe7 + +# evdev 174 (0xae): no evdev -> QKeyCode mapping (xkb keysym XF86Close) + +# evdev 175 (0xaf): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 176 (0xb0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 177 (0xb1): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollUp) + +# evdev 178 (0xb2): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollDown) + +# evdev 179 (0xb3): no evdev -> QKeyCode mapping (xkb keysym parenleft) + +# evdev 180 (0xb4): no evdev -> QKeyCode mapping (xkb keysym parenright) + +# evdev 181 (0xb5): no evdev -> QKeyCode mapping (xkb keysym XF86New) + +# evdev 182 (0xb6): no evdev -> QKeyCode mapping (xkb keysym Redo) + +# evdev 183 (0xb7): no evdev -> QKeyCode mapping (xkb keysym XF86Tools) + +# evdev 184 (0xb8): no evdev -> QKeyCode mapping (xkb keysym XF86Launch5) + +# evdev 185 (0xb9): no evdev -> QKeyCode mapping (xkb keysym XF86Launch6) + +# evdev 186 (0xba): no evdev -> QKeyCode mapping (xkb keysym XF86Launch7) + +# evdev 187 (0xbb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch8) + +# evdev 188 (0xbc): no evdev -> QKeyCode mapping (xkb keysym XF86Launch9) + +# evdev 189 (0xbd): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 190 (0xbe): no evdev -> QKeyCode mapping (xkb keysym XF86AudioMicMute) + +# evdev 191 (0xbf): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadToggle) + +# evdev 192 (0xc0): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOn) + +# evdev 193 (0xc1): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOff) + +# evdev 194 (0xc2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 195 (0xc3): no evdev -> QKeyCode mapping (xkb keysym Mode_switch) + +# evdev 196 (0xc4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 197 (0xc5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 198 (0xc6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 199 (0xc7): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 200 (0xc8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay) + +# evdev 201 (0xc9): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPause) + +# evdev 202 (0xca): no evdev -> QKeyCode mapping (xkb keysym XF86Launch3) + +# evdev 203 (0xcb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch4) + +# evdev 204 (0xcc): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchB) + +# evdev 205 (0xcd): no evdev -> QKeyCode mapping (xkb keysym XF86Suspend) + +# evdev 206 (0xce): no evdev -> QKeyCode mapping (xkb keysym XF86Close) + +# evdev 207 (0xcf): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay) + +# evdev 208 (0xd0): no evdev -> QKeyCode mapping (xkb keysym XF86AudioForward) + +# evdev 209 (0xd1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 210 (0xd2): no evdev -> QKeyCode mapping (xkb keysym Print) + +# evdev 211 (0xd3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 212 (0xd4): no evdev -> QKeyCode mapping (xkb keysym XF86WebCam) + +# evdev 213 (0xd5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 214 (0xd6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 215 (0xd7): no evdev -> QKeyCode mapping (xkb keysym XF86Mail) + +# evdev 216 (0xd8): no evdev -> QKeyCode mapping (xkb keysym XF86Messenger) + +# evdev 217 (0xd9): no evdev -> QKeyCode mapping (xkb keysym XF86Search) + +# evdev 218 (0xda): no evdev -> QKeyCode mapping (xkb keysym XF86Go) + +# evdev 219 (0xdb): no evdev -> QKeyCode mapping (xkb keysym XF86Finance) + +# evdev 220 (0xdc): no evdev -> QKeyCode mapping (xkb keysym XF86Game) + +# evdev 221 (0xdd): no evdev -> QKeyCode mapping (xkb keysym XF86Shop) + +# evdev 222 (0xde): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 223 (0xdf): no evdev -> QKeyCode mapping (xkb keysym Cancel) + +# evdev 224 (0xe0): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessDown) + +# evdev 225 (0xe1): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessUp) + +# evdev 226 (0xe2), QKeyCode "mediaselect", number 0xed +XF86AudioMedia 0xed + +# evdev 227 (0xe3): no evdev -> QKeyCode mapping (xkb keysym XF86Display) + +# evdev 228 (0xe4): no evdev -> QKeyCode mapping (xkb keysym XF86KbdLightOnOff) + +# evdev 229 (0xe5): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessDown) + +# evdev 230 (0xe6): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessUp) + +# evdev 231 (0xe7): no evdev -> QKeyCode mapping (xkb keysym XF86Send) + +# evdev 232 (0xe8): no evdev -> QKeyCode mapping (xkb keysym XF86Reply) + +# evdev 233 (0xe9): no evdev -> QKeyCode mapping (xkb keysym XF86MailForward) + +# evdev 234 (0xea): no evdev -> QKeyCode mapping (xkb keysym XF86Save) + +# evdev 235 (0xeb): no evdev -> QKeyCode mapping (xkb keysym XF86Documents) + +# evdev 236 (0xec): no evdev -> QKeyCode mapping (xkb keysym XF86Battery) + +# evdev 237 (0xed): no evdev -> QKeyCode mapping (xkb keysym XF86Bluetooth) + +# evdev 238 (0xee): no evdev -> QKeyCode mapping (xkb keysym XF86WLAN) + +# evdev 239 (0xef): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 240 (0xf0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 241 (0xf1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 242 (0xf2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 243 (0xf3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 244 (0xf4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 245 (0xf5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 246 (0xf6): no evdev -> QKeyCode mapping (xkb keysym Invalid) + +# evdev 247 (0xf7): no evdev -> QKeyCode mapping (xkb keysym Invalid) + +# +# quirks section start +# +# Sometimes multiple keysyms map to the same keycodes. +# The keycode -> keysym lookup finds only one of the +# keysyms. So append them here. +# + +Print 0x54 +Sys_Req 0x54 +Execute 0x54 +KP_Decimal 0x53 numlock +KP_Separator 0x53 numlock +Alt_R 0xb8 +ISO_Level3_Shift 0xb8 +Mode_switch 0xb8 + +# quirks section end diff --git a/app/src/main/assets/roms/keymaps/es b/app/src/main/assets/roms/keymaps/es new file mode 100644 index 0000000..fde4414 --- /dev/null +++ b/app/src/main/assets/roms/keymaps/es @@ -0,0 +1,841 @@ +# +# generated by qemu-keymap +# model : pc105 +# layout : es +# variant : - +# options : - + +# name: "Spanish" + +# modifiers +# 0: Shift +# 1: Lock +# 2: Control +# 3: Mod1 +# 4: Mod2 +# 5: Mod3 +# 6: Mod4 +# 7: Mod5 +# 8: NumLock +# 9: Alt +# 10: LevelThree +# 11: LAlt +# 12: RAlt +# 13: RControl +# 14: LControl +# 15: ScrollLock +# 16: LevelFive +# 17: AltGr +# 18: Meta +# 19: Super +# 20: Hyper + +# evdev 1 (0x1), QKeyCode "esc", number 0x1 +Escape 0x01 + +# evdev 2 (0x2), QKeyCode "1", number 0x2 +1 0x02 +exclam 0x02 shift +bar 0x02 altgr +exclamdown 0x02 shift altgr + +# evdev 3 (0x3), QKeyCode "2", number 0x3 +2 0x03 +quotedbl 0x03 shift +at 0x03 altgr +oneeighth 0x03 shift altgr + +# evdev 4 (0x4), QKeyCode "3", number 0x4 +3 0x04 +periodcentered 0x04 shift +numbersign 0x04 altgr +sterling 0x04 shift altgr + +# evdev 5 (0x5), QKeyCode "4", number 0x5 +4 0x05 +dollar 0x05 shift +asciitilde 0x05 altgr + +# evdev 6 (0x6), QKeyCode "5", number 0x6 +5 0x06 +percent 0x06 shift +onehalf 0x06 altgr +threeeighths 0x06 shift altgr + +# evdev 7 (0x7), QKeyCode "6", number 0x7 +6 0x07 +ampersand 0x07 shift +notsign 0x07 altgr +fiveeighths 0x07 shift altgr + +# evdev 8 (0x8), QKeyCode "7", number 0x8 +7 0x08 +slash 0x08 shift +braceleft 0x08 altgr +seveneighths 0x08 shift altgr + +# evdev 9 (0x9), QKeyCode "8", number 0x9 +8 0x09 +parenleft 0x09 shift +bracketleft 0x09 altgr +trademark 0x09 shift altgr + +# evdev 10 (0xa), QKeyCode "9", number 0xa +9 0x0a +parenright 0x0a shift +bracketright 0x0a altgr +plusminus 0x0a shift altgr + +# evdev 11 (0xb), QKeyCode "0", number 0xb +0 0x0b +equal 0x0b shift +braceright 0x0b altgr +degree 0x0b shift altgr + +# evdev 12 (0xc), QKeyCode "minus", number 0xc +apostrophe 0x0c +question 0x0c shift +backslash 0x0c altgr +questiondown 0x0c shift altgr + +# evdev 13 (0xd), QKeyCode "equal", number 0xd +exclamdown 0x0d +questiondown 0x0d shift +dead_tilde 0x0d altgr +asciitilde 0x0d shift altgr + +# evdev 14 (0xe), QKeyCode "backspace", number 0xe +BackSpace 0x0e + +# evdev 15 (0xf), QKeyCode "tab", number 0xf +Tab 0x0f +ISO_Left_Tab 0x0f shift + +# evdev 16 (0x10), QKeyCode "q", number 0x10 +q 0x10 +Q 0x10 shift +at 0x10 altgr +Greek_OMEGA 0x10 shift altgr + +# evdev 17 (0x11), QKeyCode "w", number 0x11 +w 0x11 +W 0x11 shift +lstroke 0x11 altgr +Lstroke 0x11 shift altgr + +# evdev 18 (0x12), QKeyCode "e", number 0x12 +e 0x12 +E 0x12 shift +EuroSign 0x12 altgr +cent 0x12 shift altgr + +# evdev 19 (0x13), QKeyCode "r", number 0x13 +r 0x13 +R 0x13 shift +paragraph 0x13 altgr +registered 0x13 shift altgr + +# evdev 20 (0x14), QKeyCode "t", number 0x14 +t 0x14 +T 0x14 shift +tslash 0x14 altgr +Tslash 0x14 shift altgr + +# evdev 21 (0x15), QKeyCode "y", number 0x15 +y 0x15 +Y 0x15 shift +leftarrow 0x15 altgr +yen 0x15 shift altgr + +# evdev 22 (0x16), QKeyCode "u", number 0x16 +u 0x16 +U 0x16 shift +downarrow 0x16 altgr +uparrow 0x16 shift altgr + +# evdev 23 (0x17), QKeyCode "i", number 0x17 +i 0x17 +I 0x17 shift +rightarrow 0x17 altgr +idotless 0x17 shift altgr + +# evdev 24 (0x18), QKeyCode "o", number 0x18 +o 0x18 +O 0x18 shift +oslash 0x18 altgr +Oslash 0x18 shift altgr + +# evdev 25 (0x19), QKeyCode "p", number 0x19 +p 0x19 +P 0x19 shift +thorn 0x19 altgr +THORN 0x19 shift altgr + +# evdev 26 (0x1a), QKeyCode "bracket_left", number 0x1a +dead_grave 0x1a +dead_circumflex 0x1a shift +bracketleft 0x1a altgr +dead_abovering 0x1a shift altgr + +# evdev 27 (0x1b), QKeyCode "bracket_right", number 0x1b +plus 0x1b +asterisk 0x1b shift +bracketright 0x1b altgr +dead_macron 0x1b shift altgr + +# evdev 28 (0x1c), QKeyCode "ret", number 0x1c +Return 0x1c + +# evdev 29 (0x1d), QKeyCode "ctrl", number 0x1d +Control_L 0x1d + +# evdev 30 (0x1e), QKeyCode "a", number 0x1e +a 0x1e +A 0x1e shift +ae 0x1e altgr +AE 0x1e shift altgr + +# evdev 31 (0x1f), QKeyCode "s", number 0x1f +s 0x1f +S 0x1f shift +ssharp 0x1f altgr +section 0x1f shift altgr + +# evdev 32 (0x20), QKeyCode "d", number 0x20 +d 0x20 +D 0x20 shift +eth 0x20 altgr +ETH 0x20 shift altgr + +# evdev 33 (0x21), QKeyCode "f", number 0x21 +f 0x21 +F 0x21 shift +dstroke 0x21 altgr +ordfeminine 0x21 shift altgr + +# evdev 34 (0x22), QKeyCode "g", number 0x22 +g 0x22 +G 0x22 shift +eng 0x22 altgr +ENG 0x22 shift altgr + +# evdev 35 (0x23), QKeyCode "h", number 0x23 +h 0x23 +H 0x23 shift +hstroke 0x23 altgr +Hstroke 0x23 shift altgr + +# evdev 36 (0x24), QKeyCode "j", number 0x24 +j 0x24 +J 0x24 shift +dead_hook 0x24 altgr +dead_horn 0x24 shift altgr + +# evdev 37 (0x25), QKeyCode "k", number 0x25 +k 0x25 +K 0x25 shift +kra 0x25 altgr +ampersand 0x25 shift altgr + +# evdev 38 (0x26), QKeyCode "l", number 0x26 +l 0x26 +L 0x26 shift +lstroke 0x26 altgr +Lstroke 0x26 shift altgr + +# evdev 39 (0x27), QKeyCode "semicolon", number 0x27 +ntilde 0x27 +Ntilde 0x27 shift +asciitilde 0x27 altgr +dead_doubleacute 0x27 shift altgr + +# evdev 40 (0x28), QKeyCode "apostrophe", number 0x28 +dead_acute 0x28 +dead_diaeresis 0x28 shift +braceleft 0x28 altgr + +# evdev 41 (0x29), QKeyCode "grave_accent", number 0x29 +masculine 0x29 +ordfeminine 0x29 shift +backslash 0x29 altgr + +# evdev 42 (0x2a), QKeyCode "shift", number 0x2a +Shift_L 0x2a + +# evdev 43 (0x2b), QKeyCode "backslash", number 0x2b +ccedilla 0x2b +Ccedilla 0x2b shift +braceright 0x2b altgr +dead_breve 0x2b shift altgr + +# evdev 44 (0x2c), QKeyCode "z", number 0x2c +z 0x2c +Z 0x2c shift +guillemotleft 0x2c altgr +less 0x2c shift altgr + +# evdev 45 (0x2d), QKeyCode "x", number 0x2d +x 0x2d +X 0x2d shift +guillemotright 0x2d altgr +greater 0x2d shift altgr + +# evdev 46 (0x2e), QKeyCode "c", number 0x2e +c 0x2e +C 0x2e shift +cent 0x2e altgr +copyright 0x2e shift altgr + +# evdev 47 (0x2f), QKeyCode "v", number 0x2f +v 0x2f +V 0x2f shift +leftdoublequotemark 0x2f altgr +leftsinglequotemark 0x2f shift altgr + +# evdev 48 (0x30), QKeyCode "b", number 0x30 +b 0x30 +B 0x30 shift +rightdoublequotemark 0x30 altgr +rightsinglequotemark 0x30 shift altgr + +# evdev 49 (0x31), QKeyCode "n", number 0x31 +n 0x31 +N 0x31 shift + +# evdev 50 (0x32), QKeyCode "m", number 0x32 +m 0x32 +M 0x32 shift +mu 0x32 altgr +masculine 0x32 shift altgr + +# evdev 51 (0x33), QKeyCode "comma", number 0x33 +comma 0x33 +semicolon 0x33 shift +horizconnector 0x33 altgr +multiply 0x33 shift altgr + +# evdev 52 (0x34), QKeyCode "dot", number 0x34 +period 0x34 +colon 0x34 shift +periodcentered 0x34 altgr +division 0x34 shift altgr + +# evdev 53 (0x35), QKeyCode "slash", number 0x35 +minus 0x35 +underscore 0x35 shift +dead_belowdot 0x35 altgr +dead_abovedot 0x35 shift altgr + +# evdev 54 (0x36), QKeyCode "shift_r", number 0x36 +Shift_R 0x36 + +# evdev 55 (0x37), QKeyCode "kp_multiply", number 0x37 +KP_Multiply 0x37 + +# evdev 56 (0x38), QKeyCode "alt", number 0x38 +Alt_L 0x38 +Meta_L 0x38 shift + +# evdev 57 (0x39), QKeyCode "spc", number 0x39 +space 0x39 + +# evdev 58 (0x3a), QKeyCode "caps_lock", number 0x3a +Caps_Lock 0x3a + +# evdev 59 (0x3b), QKeyCode "f1", number 0x3b +F1 0x3b + +# evdev 60 (0x3c), QKeyCode "f2", number 0x3c +F2 0x3c + +# evdev 61 (0x3d), QKeyCode "f3", number 0x3d +F3 0x3d + +# evdev 62 (0x3e), QKeyCode "f4", number 0x3e +F4 0x3e + +# evdev 63 (0x3f), QKeyCode "f5", number 0x3f +F5 0x3f + +# evdev 64 (0x40), QKeyCode "f6", number 0x40 +F6 0x40 + +# evdev 65 (0x41), QKeyCode "f7", number 0x41 +F7 0x41 + +# evdev 66 (0x42), QKeyCode "f8", number 0x42 +F8 0x42 + +# evdev 67 (0x43), QKeyCode "f9", number 0x43 +F9 0x43 + +# evdev 68 (0x44), QKeyCode "f10", number 0x44 +F10 0x44 + +# evdev 69 (0x45), QKeyCode "num_lock", number 0x45 +Num_Lock 0x45 + +# evdev 70 (0x46), QKeyCode "scroll_lock", number 0x46 +Scroll_Lock 0x46 + +# evdev 71 (0x47), QKeyCode "kp_7", number 0x47 +KP_Home 0x47 +KP_7 0x47 numlock + +# evdev 72 (0x48), QKeyCode "kp_8", number 0x48 +KP_Up 0x48 +KP_8 0x48 numlock + +# evdev 73 (0x49), QKeyCode "kp_9", number 0x49 +KP_Prior 0x49 +KP_9 0x49 numlock + +# evdev 74 (0x4a), QKeyCode "kp_subtract", number 0x4a +KP_Subtract 0x4a + +# evdev 75 (0x4b), QKeyCode "kp_4", number 0x4b +KP_Left 0x4b +KP_4 0x4b numlock + +# evdev 76 (0x4c), QKeyCode "kp_5", number 0x4c +KP_Begin 0x4c +KP_5 0x4c numlock + +# evdev 77 (0x4d), QKeyCode "kp_6", number 0x4d +KP_Right 0x4d +KP_6 0x4d numlock + +# evdev 78 (0x4e), QKeyCode "kp_add", number 0x4e +KP_Add 0x4e + +# evdev 79 (0x4f), QKeyCode "kp_1", number 0x4f +KP_End 0x4f +KP_1 0x4f numlock + +# evdev 80 (0x50), QKeyCode "kp_2", number 0x50 +KP_Down 0x50 +KP_2 0x50 numlock + +# evdev 81 (0x51), QKeyCode "kp_3", number 0x51 +KP_Next 0x51 +KP_3 0x51 numlock + +# evdev 82 (0x52), QKeyCode "kp_0", number 0x52 +KP_Insert 0x52 +KP_0 0x52 numlock + +# evdev 83 (0x53), QKeyCode "kp_decimal", number 0x53 +KP_Delete 0x53 +KP_Decimal 0x53 numlock + +# evdev 84 (0x54): no evdev -> QKeyCode mapping (xkb keysym ISO_Level3_Shift) + +# evdev 85 (0x55): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 86 (0x56), QKeyCode "less", number 0x56 +less 0x56 +greater 0x56 shift +bar 0x56 altgr +brokenbar 0x56 shift altgr + +# evdev 87 (0x57), QKeyCode "f11", number 0x57 +F11 0x57 + +# evdev 88 (0x58), QKeyCode "f12", number 0x58 +F12 0x58 + +# evdev 89 (0x59), QKeyCode "ro", number 0x73 + +# evdev 90 (0x5a): no evdev -> QKeyCode mapping (xkb keysym Katakana) + +# evdev 91 (0x5b), QKeyCode "hiragana", number 0x77 +Hiragana 0x77 + +# evdev 92 (0x5c), QKeyCode "henkan", number 0x79 +Henkan_Mode 0x79 + +# evdev 93 (0x5d), QKeyCode "katakanahiragana", number 0x70 +Hiragana_Katakana 0x70 + +# evdev 94 (0x5e), QKeyCode "muhenkan", number 0x7b +Muhenkan 0x7b + +# evdev 95 (0x5f): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 96 (0x60), QKeyCode "kp_enter", number 0x9c +KP_Enter 0x9c + +# evdev 97 (0x61), QKeyCode "ctrl_r", number 0x9d +Control_R 0x9d + +# evdev 98 (0x62), QKeyCode "kp_divide", number 0xb5 +KP_Divide 0xb5 + +# evdev 99 (0x63), QKeyCode "sysrq", number 0x54 +Print 0x54 + +# evdev 100 (0x64), QKeyCode "alt_r", number 0xb8 +ISO_Level3_Shift 0xb8 + +# evdev 101 (0x65), QKeyCode "lf", number 0x5b +Linefeed 0x5b + +# evdev 102 (0x66), QKeyCode "home", number 0xc7 +Home 0xc7 + +# evdev 103 (0x67), QKeyCode "up", number 0xc8 +Up 0xc8 + +# evdev 104 (0x68), QKeyCode "pgup", number 0xc9 +Prior 0xc9 + +# evdev 105 (0x69), QKeyCode "left", number 0xcb +Left 0xcb + +# evdev 106 (0x6a), QKeyCode "right", number 0xcd +Right 0xcd + +# evdev 107 (0x6b), QKeyCode "end", number 0xcf +End 0xcf + +# evdev 108 (0x6c), QKeyCode "down", number 0xd0 +Down 0xd0 + +# evdev 109 (0x6d), QKeyCode "pgdn", number 0xd1 +Next 0xd1 + +# evdev 110 (0x6e), QKeyCode "insert", number 0xd2 +Insert 0xd2 + +# evdev 111 (0x6f), QKeyCode "delete", number 0xd3 +Delete 0xd3 + +# evdev 112 (0x70): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 113 (0x71), QKeyCode "audiomute", number 0xa0 +XF86AudioMute 0xa0 + +# evdev 114 (0x72), QKeyCode "volumedown", number 0xae +XF86AudioLowerVolume 0xae + +# evdev 115 (0x73), QKeyCode "volumeup", number 0xb0 +XF86AudioRaiseVolume 0xb0 + +# evdev 116 (0x74), QKeyCode "power", number 0xde +XF86PowerOff 0xde + +# evdev 117 (0x75), QKeyCode "kp_equals", number 0x59 +KP_Equal 0x59 + +# evdev 118 (0x76): no evdev -> QKeyCode mapping (xkb keysym plusminus) + +# evdev 119 (0x77), QKeyCode "pause", number 0xc6 +Pause 0xc6 + +# evdev 120 (0x78): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchA) + +# evdev 121 (0x79), QKeyCode "kp_comma", number 0x7e +KP_Decimal 0x7e + +# evdev 122 (0x7a): no evdev -> QKeyCode mapping (xkb keysym Hangul) + +# evdev 123 (0x7b): no evdev -> QKeyCode mapping (xkb keysym Hangul_Hanja) + +# evdev 124 (0x7c), QKeyCode "yen", number 0x7d + +# evdev 125 (0x7d), QKeyCode "meta_l", number 0xdb +Super_L 0xdb + +# evdev 126 (0x7e), QKeyCode "meta_r", number 0xdc +Super_R 0xdc + +# evdev 127 (0x7f), QKeyCode "compose", number 0xdd +Menu 0xdd + +# evdev 128 (0x80), QKeyCode "stop", number 0xe8 +Cancel 0xe8 + +# evdev 129 (0x81), QKeyCode "again", number 0x85 +Redo 0x85 + +# evdev 130 (0x82), QKeyCode "props", number 0x86 +SunProps 0x86 + +# evdev 131 (0x83), QKeyCode "undo", number 0x87 +Undo 0x87 + +# evdev 132 (0x84), QKeyCode "front", number 0x8c +SunFront 0x8c + +# evdev 133 (0x85), QKeyCode "copy", number 0xf8 +XF86Copy 0xf8 + +# evdev 134 (0x86), QKeyCode "open", number 0x64 +XF86Open 0x64 + +# evdev 135 (0x87), QKeyCode "paste", number 0x65 +XF86Paste 0x65 + +# evdev 136 (0x88), QKeyCode "find", number 0xc1 +Find 0xc1 + +# evdev 137 (0x89), QKeyCode "cut", number 0xbc +XF86Cut 0xbc + +# evdev 138 (0x8a), QKeyCode "help", number 0xf5 +Help 0xf5 + +# evdev 139 (0x8b), QKeyCode "menu", number 0x9e +XF86MenuKB 0x9e + +# evdev 140 (0x8c), QKeyCode "calculator", number 0xa1 +XF86Calculator 0xa1 + +# evdev 141 (0x8d): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 142 (0x8e), QKeyCode "sleep", number 0xdf +XF86Sleep 0xdf + +# evdev 143 (0x8f), QKeyCode "wake", number 0xe3 +XF86WakeUp 0xe3 + +# evdev 144 (0x90): no evdev -> QKeyCode mapping (xkb keysym XF86Explorer) + +# evdev 145 (0x91): no evdev -> QKeyCode mapping (xkb keysym XF86Send) + +# evdev 146 (0x92): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 147 (0x93): no evdev -> QKeyCode mapping (xkb keysym XF86Xfer) + +# evdev 148 (0x94): no evdev -> QKeyCode mapping (xkb keysym XF86Launch1) + +# evdev 149 (0x95): no evdev -> QKeyCode mapping (xkb keysym XF86Launch2) + +# evdev 150 (0x96): no evdev -> QKeyCode mapping (xkb keysym XF86WWW) + +# evdev 151 (0x97): no evdev -> QKeyCode mapping (xkb keysym XF86DOS) + +# evdev 152 (0x98): no evdev -> QKeyCode mapping (xkb keysym XF86ScreenSaver) + +# evdev 153 (0x99): no evdev -> QKeyCode mapping (xkb keysym XF86RotateWindows) + +# evdev 154 (0x9a): no evdev -> QKeyCode mapping (xkb keysym XF86TaskPane) + +# evdev 155 (0x9b), QKeyCode "mail", number 0xec +XF86Mail 0xec + +# evdev 156 (0x9c), QKeyCode "ac_bookmarks", number 0xe6 +XF86Favorites 0xe6 + +# evdev 157 (0x9d), QKeyCode "computer", number 0xeb +XF86MyComputer 0xeb + +# evdev 158 (0x9e), QKeyCode "ac_back", number 0xea +XF86Back 0xea + +# evdev 159 (0x9f), QKeyCode "ac_forward", number 0xe9 +XF86Forward 0xe9 + +# evdev 160 (0xa0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 161 (0xa1): no evdev -> QKeyCode mapping (xkb keysym XF86Eject) + +# evdev 162 (0xa2): no evdev -> QKeyCode mapping (xkb keysym XF86Eject) + +# evdev 163 (0xa3), QKeyCode "audionext", number 0x99 +XF86AudioNext 0x99 + +# evdev 164 (0xa4), QKeyCode "audioplay", number 0xa2 +XF86AudioPlay 0xa2 +XF86AudioPause 0xa2 shift + +# evdev 165 (0xa5), QKeyCode "audioprev", number 0x90 +XF86AudioPrev 0x90 + +# evdev 166 (0xa6), QKeyCode "audiostop", number 0xa4 +XF86AudioStop 0xa4 +XF86Eject 0xa4 shift + +# evdev 167 (0xa7): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRecord) + +# evdev 168 (0xa8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRewind) + +# evdev 169 (0xa9): no evdev -> QKeyCode mapping (xkb keysym XF86Phone) + +# evdev 170 (0xaa): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 171 (0xab): no evdev -> QKeyCode mapping (xkb keysym XF86Tools) + +# evdev 172 (0xac), QKeyCode "ac_home", number 0xb2 +XF86HomePage 0xb2 + +# evdev 173 (0xad), QKeyCode "ac_refresh", number 0xe7 +XF86Reload 0xe7 + +# evdev 174 (0xae): no evdev -> QKeyCode mapping (xkb keysym XF86Close) + +# evdev 175 (0xaf): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 176 (0xb0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 177 (0xb1): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollUp) + +# evdev 178 (0xb2): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollDown) + +# evdev 179 (0xb3): no evdev -> QKeyCode mapping (xkb keysym parenleft) + +# evdev 180 (0xb4): no evdev -> QKeyCode mapping (xkb keysym parenright) + +# evdev 181 (0xb5): no evdev -> QKeyCode mapping (xkb keysym XF86New) + +# evdev 182 (0xb6): no evdev -> QKeyCode mapping (xkb keysym Redo) + +# evdev 183 (0xb7): no evdev -> QKeyCode mapping (xkb keysym XF86Tools) + +# evdev 184 (0xb8): no evdev -> QKeyCode mapping (xkb keysym XF86Launch5) + +# evdev 185 (0xb9): no evdev -> QKeyCode mapping (xkb keysym XF86Launch6) + +# evdev 186 (0xba): no evdev -> QKeyCode mapping (xkb keysym XF86Launch7) + +# evdev 187 (0xbb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch8) + +# evdev 188 (0xbc): no evdev -> QKeyCode mapping (xkb keysym XF86Launch9) + +# evdev 189 (0xbd): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 190 (0xbe): no evdev -> QKeyCode mapping (xkb keysym XF86AudioMicMute) + +# evdev 191 (0xbf): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadToggle) + +# evdev 192 (0xc0): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOn) + +# evdev 193 (0xc1): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOff) + +# evdev 194 (0xc2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 195 (0xc3): no evdev -> QKeyCode mapping (xkb keysym Mode_switch) + +# evdev 196 (0xc4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 197 (0xc5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 198 (0xc6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 199 (0xc7): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 200 (0xc8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay) + +# evdev 201 (0xc9): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPause) + +# evdev 202 (0xca): no evdev -> QKeyCode mapping (xkb keysym XF86Launch3) + +# evdev 203 (0xcb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch4) + +# evdev 204 (0xcc): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchB) + +# evdev 205 (0xcd): no evdev -> QKeyCode mapping (xkb keysym XF86Suspend) + +# evdev 206 (0xce): no evdev -> QKeyCode mapping (xkb keysym XF86Close) + +# evdev 207 (0xcf): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay) + +# evdev 208 (0xd0): no evdev -> QKeyCode mapping (xkb keysym XF86AudioForward) + +# evdev 209 (0xd1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 210 (0xd2): no evdev -> QKeyCode mapping (xkb keysym Print) + +# evdev 211 (0xd3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 212 (0xd4): no evdev -> QKeyCode mapping (xkb keysym XF86WebCam) + +# evdev 213 (0xd5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 214 (0xd6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 215 (0xd7): no evdev -> QKeyCode mapping (xkb keysym XF86Mail) + +# evdev 216 (0xd8): no evdev -> QKeyCode mapping (xkb keysym XF86Messenger) + +# evdev 217 (0xd9): no evdev -> QKeyCode mapping (xkb keysym XF86Search) + +# evdev 218 (0xda): no evdev -> QKeyCode mapping (xkb keysym XF86Go) + +# evdev 219 (0xdb): no evdev -> QKeyCode mapping (xkb keysym XF86Finance) + +# evdev 220 (0xdc): no evdev -> QKeyCode mapping (xkb keysym XF86Game) + +# evdev 221 (0xdd): no evdev -> QKeyCode mapping (xkb keysym XF86Shop) + +# evdev 222 (0xde): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 223 (0xdf): no evdev -> QKeyCode mapping (xkb keysym Cancel) + +# evdev 224 (0xe0): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessDown) + +# evdev 225 (0xe1): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessUp) + +# evdev 226 (0xe2), QKeyCode "mediaselect", number 0xed +XF86AudioMedia 0xed + +# evdev 227 (0xe3): no evdev -> QKeyCode mapping (xkb keysym XF86Display) + +# evdev 228 (0xe4): no evdev -> QKeyCode mapping (xkb keysym XF86KbdLightOnOff) + +# evdev 229 (0xe5): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessDown) + +# evdev 230 (0xe6): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessUp) + +# evdev 231 (0xe7): no evdev -> QKeyCode mapping (xkb keysym XF86Send) + +# evdev 232 (0xe8): no evdev -> QKeyCode mapping (xkb keysym XF86Reply) + +# evdev 233 (0xe9): no evdev -> QKeyCode mapping (xkb keysym XF86MailForward) + +# evdev 234 (0xea): no evdev -> QKeyCode mapping (xkb keysym XF86Save) + +# evdev 235 (0xeb): no evdev -> QKeyCode mapping (xkb keysym XF86Documents) + +# evdev 236 (0xec): no evdev -> QKeyCode mapping (xkb keysym XF86Battery) + +# evdev 237 (0xed): no evdev -> QKeyCode mapping (xkb keysym XF86Bluetooth) + +# evdev 238 (0xee): no evdev -> QKeyCode mapping (xkb keysym XF86WLAN) + +# evdev 239 (0xef): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 240 (0xf0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 241 (0xf1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 242 (0xf2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 243 (0xf3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 244 (0xf4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 245 (0xf5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 246 (0xf6): no evdev -> QKeyCode mapping (xkb keysym Invalid) + +# evdev 247 (0xf7): no evdev -> QKeyCode mapping (xkb keysym Invalid) + +# +# quirks section start +# +# Sometimes multiple keysyms map to the same keycodes. +# The keycode -> keysym lookup finds only one of the +# keysyms. So append them here. +# + +Print 0x54 +Sys_Req 0x54 +Execute 0x54 +KP_Decimal 0x53 numlock +KP_Separator 0x53 numlock +Alt_R 0xb8 +ISO_Level3_Shift 0xb8 +Mode_switch 0xb8 + +# quirks section end diff --git a/app/src/main/assets/roms/keymaps/et b/app/src/main/assets/roms/keymaps/et new file mode 100644 index 0000000..a5dcbd1 --- /dev/null +++ b/app/src/main/assets/roms/keymaps/et @@ -0,0 +1,751 @@ +# +# generated by qemu-keymap +# model : pc105 +# layout : et +# variant : - +# options : - + +# name: "Amharic" + +# modifiers +# 0: Shift +# 1: Lock +# 2: Control +# 3: Mod1 +# 4: Mod2 +# 5: Mod3 +# 6: Mod4 +# 7: Mod5 +# 8: NumLock +# 9: Alt +# 10: LevelThree +# 11: LAlt +# 12: RAlt +# 13: RControl +# 14: LControl +# 15: ScrollLock +# 16: LevelFive +# 17: AltGr +# 18: Meta +# 19: Super +# 20: Hyper + +# evdev 1 (0x1), QKeyCode "esc", number 0x1 +Escape 0x01 + +# evdev 2 (0x2), QKeyCode "1", number 0x2 +U1369 0x02 +U1372 0x02 shift + +# evdev 3 (0x3), QKeyCode "2", number 0x3 +U136A 0x03 +U1373 0x03 shift + +# evdev 4 (0x4), QKeyCode "3", number 0x4 +U136B 0x04 +U1374 0x04 shift + +# evdev 5 (0x5), QKeyCode "4", number 0x5 +U136C 0x05 +U1375 0x05 shift + +# evdev 6 (0x6), QKeyCode "5", number 0x6 +U136D 0x06 +U1376 0x06 shift + +# evdev 7 (0x7), QKeyCode "6", number 0x7 +U136E 0x07 +U1377 0x07 shift + +# evdev 8 (0x8), QKeyCode "7", number 0x8 +U136F 0x08 +U1378 0x08 shift + +# evdev 9 (0x9), QKeyCode "8", number 0x9 +U1370 0x09 +U1379 0x09 shift + +# evdev 10 (0xa), QKeyCode "9", number 0xa +U1371 0x0a +U137A 0x0a shift + +# evdev 11 (0xb), QKeyCode "0", number 0xb +U137B 0x0b +U137C 0x0b shift + +# evdev 12 (0xc), QKeyCode "minus", number 0xc +minus 0x0c +underscore 0x0c shift + +# evdev 13 (0xd), QKeyCode "equal", number 0xd +equal 0x0d +plus 0x0d shift + +# evdev 14 (0xe), QKeyCode "backspace", number 0xe +BackSpace 0x0e + +# evdev 15 (0xf), QKeyCode "tab", number 0xf +Tab 0x0f +ISO_Left_Tab 0x0f shift + +# evdev 16 (0x10), QKeyCode "q", number 0x10 +U1240 0x10 +U1250 0x10 shift + +# evdev 17 (0x11), QKeyCode "w", number 0x11 +U12C8 0x11 +VoidSymbol 0x11 shift + +# evdev 18 (0x12), QKeyCode "e", number 0x12 +UFE69 0x12 +UFE70 0x12 shift + +# evdev 19 (0x13), QKeyCode "r", number 0x13 +U1228 0x13 +VoidSymbol 0x13 shift + +# evdev 20 (0x14), QKeyCode "t", number 0x14 +U1270 0x14 +U1320 0x14 shift + +# evdev 21 (0x15), QKeyCode "y", number 0x15 +U12E8 0x15 +VoidSymbol 0x15 shift + +# evdev 22 (0x16), QKeyCode "u", number 0x16 +UFE75 0x16 +UFE76 0x16 shift + +# evdev 23 (0x17), QKeyCode "i", number 0x17 +UFE71 0x17 +UFE72 0x17 shift + +# evdev 24 (0x18), QKeyCode "o", number 0x18 +UFE73 0x18 +UFE74 0x18 shift + +# evdev 25 (0x19), QKeyCode "p", number 0x19 +U1350 0x19 +U1330 0x19 shift + +# evdev 26 (0x1a), QKeyCode "bracket_left", number 0x1a +U1340 0x1a +U1338 0x1a shift + +# evdev 27 (0x1b), QKeyCode "bracket_right", number 0x1b +U1328 0x1b +U1280 0x1b shift + +# evdev 28 (0x1c), QKeyCode "ret", number 0x1c +Return 0x1c + +# evdev 29 (0x1d), QKeyCode "ctrl", number 0x1d +Control_L 0x1d + +# evdev 30 (0x1e), QKeyCode "a", number 0x1e +UFE67 0x1e +UFE68 0x1e shift + +# evdev 31 (0x1f), QKeyCode "s", number 0x1f +U1230 0x1f +U1220 0x1f shift + +# evdev 32 (0x20), QKeyCode "d", number 0x20 +U12F0 0x20 +U12F8 0x20 shift + +# evdev 33 (0x21), QKeyCode "f", number 0x21 +U1348 0x21 +VoidSymbol 0x21 shift + +# evdev 34 (0x22), QKeyCode "g", number 0x22 +U1308 0x22 +U1318 0x22 shift + +# evdev 35 (0x23), QKeyCode "h", number 0x23 +U1200 0x23 +U1210 0x23 shift + +# evdev 36 (0x24), QKeyCode "j", number 0x24 +U1300 0x24 +VoidSymbol 0x24 shift + +# evdev 37 (0x25), QKeyCode "k", number 0x25 +U12A8 0x25 +U12B8 0x25 shift + +# evdev 38 (0x26), QKeyCode "l", number 0x26 +U1208 0x26 +VoidSymbol 0x26 shift + +# evdev 39 (0x27), QKeyCode "semicolon", number 0x27 +U1362 0x27 +U1361 0x27 shift + +# evdev 40 (0x28), QKeyCode "apostrophe", number 0x28 +U1366 0x28 +U1365 0x28 shift + +# evdev 41 (0x29), QKeyCode "grave_accent", number 0x29 + +# evdev 42 (0x2a), QKeyCode "shift", number 0x2a +Shift_L 0x2a + +# evdev 43 (0x2b), QKeyCode "backslash", number 0x2b +VoidSymbol 0x2b +U2010 0x2b shift + +# evdev 44 (0x2c), QKeyCode "z", number 0x2c +U12D8 0x2c +U12E0 0x2c shift + +# evdev 45 (0x2d), QKeyCode "x", number 0x2d +U12A0 0x2d +U12D0 0x2d shift + +# evdev 46 (0x2e), QKeyCode "c", number 0x2e +U1278 0x2e +UFE78 0x2e shift + +# evdev 47 (0x2f), QKeyCode "v", number 0x2f +U1238 0x2f +U1268 0x2f shift + +# evdev 48 (0x30), QKeyCode "b", number 0x30 +U1260 0x30 +VoidSymbol 0x30 shift + +# evdev 49 (0x31), QKeyCode "n", number 0x31 +U1290 0x31 +U1298 0x31 shift + +# evdev 50 (0x32), QKeyCode "m", number 0x32 +U1218 0x32 +VoidSymbol 0x32 shift + +# evdev 51 (0x33), QKeyCode "comma", number 0x33 +U1363 0x33 +VoidSymbol 0x33 shift + +# evdev 52 (0x34), QKeyCode "dot", number 0x34 +U1364 0x34 +VoidSymbol 0x34 shift + +# evdev 53 (0x35), QKeyCode "slash", number 0x35 +U1367 0x35 +question 0x35 shift + +# evdev 54 (0x36), QKeyCode "shift_r", number 0x36 +Shift_R 0x36 + +# evdev 55 (0x37), QKeyCode "kp_multiply", number 0x37 +KP_Multiply 0x37 + +# evdev 56 (0x38), QKeyCode "alt", number 0x38 +Alt_L 0x38 +Meta_L 0x38 shift + +# evdev 57 (0x39), QKeyCode "spc", number 0x39 +space 0x39 + +# evdev 58 (0x3a), QKeyCode "caps_lock", number 0x3a +Caps_Lock 0x3a + +# evdev 59 (0x3b), QKeyCode "f1", number 0x3b +F1 0x3b + +# evdev 60 (0x3c), QKeyCode "f2", number 0x3c +F2 0x3c + +# evdev 61 (0x3d), QKeyCode "f3", number 0x3d +F3 0x3d + +# evdev 62 (0x3e), QKeyCode "f4", number 0x3e +F4 0x3e + +# evdev 63 (0x3f), QKeyCode "f5", number 0x3f +F5 0x3f + +# evdev 64 (0x40), QKeyCode "f6", number 0x40 +F6 0x40 + +# evdev 65 (0x41), QKeyCode "f7", number 0x41 +F7 0x41 + +# evdev 66 (0x42), QKeyCode "f8", number 0x42 +F8 0x42 + +# evdev 67 (0x43), QKeyCode "f9", number 0x43 +F9 0x43 + +# evdev 68 (0x44), QKeyCode "f10", number 0x44 +F10 0x44 + +# evdev 69 (0x45), QKeyCode "num_lock", number 0x45 +Num_Lock 0x45 + +# evdev 70 (0x46), QKeyCode "scroll_lock", number 0x46 +Scroll_Lock 0x46 + +# evdev 71 (0x47), QKeyCode "kp_7", number 0x47 +KP_Home 0x47 +KP_7 0x47 numlock + +# evdev 72 (0x48), QKeyCode "kp_8", number 0x48 +KP_Up 0x48 +KP_8 0x48 numlock + +# evdev 73 (0x49), QKeyCode "kp_9", number 0x49 +KP_Prior 0x49 +KP_9 0x49 numlock + +# evdev 74 (0x4a), QKeyCode "kp_subtract", number 0x4a +KP_Subtract 0x4a + +# evdev 75 (0x4b), QKeyCode "kp_4", number 0x4b +KP_Left 0x4b +KP_4 0x4b numlock + +# evdev 76 (0x4c), QKeyCode "kp_5", number 0x4c +KP_Begin 0x4c +KP_5 0x4c numlock + +# evdev 77 (0x4d), QKeyCode "kp_6", number 0x4d +KP_Right 0x4d +KP_6 0x4d numlock + +# evdev 78 (0x4e), QKeyCode "kp_add", number 0x4e +KP_Add 0x4e + +# evdev 79 (0x4f), QKeyCode "kp_1", number 0x4f +KP_End 0x4f +KP_1 0x4f numlock + +# evdev 80 (0x50), QKeyCode "kp_2", number 0x50 +KP_Down 0x50 +KP_2 0x50 numlock + +# evdev 81 (0x51), QKeyCode "kp_3", number 0x51 +KP_Next 0x51 +KP_3 0x51 numlock + +# evdev 82 (0x52), QKeyCode "kp_0", number 0x52 +KP_Insert 0x52 +KP_0 0x52 numlock + +# evdev 83 (0x53), QKeyCode "kp_decimal", number 0x53 +KP_Delete 0x53 +KP_Decimal 0x53 numlock + +# evdev 84 (0x54): no evdev -> QKeyCode mapping (xkb keysym ISO_Level3_Shift) + +# evdev 85 (0x55): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 86 (0x56), QKeyCode "less", number 0x56 +less 0x56 +greater 0x56 shift +bar 0x56 altgr +brokenbar 0x56 shift altgr + +# evdev 87 (0x57), QKeyCode "f11", number 0x57 +F11 0x57 + +# evdev 88 (0x58), QKeyCode "f12", number 0x58 +F12 0x58 + +# evdev 89 (0x59), QKeyCode "ro", number 0x73 + +# evdev 90 (0x5a): no evdev -> QKeyCode mapping (xkb keysym Katakana) + +# evdev 91 (0x5b), QKeyCode "hiragana", number 0x77 +Hiragana 0x77 + +# evdev 92 (0x5c), QKeyCode "henkan", number 0x79 +Henkan_Mode 0x79 + +# evdev 93 (0x5d), QKeyCode "katakanahiragana", number 0x70 +Hiragana_Katakana 0x70 + +# evdev 94 (0x5e), QKeyCode "muhenkan", number 0x7b +Muhenkan 0x7b + +# evdev 95 (0x5f): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 96 (0x60), QKeyCode "kp_enter", number 0x9c +KP_Enter 0x9c + +# evdev 97 (0x61), QKeyCode "ctrl_r", number 0x9d +Control_R 0x9d + +# evdev 98 (0x62), QKeyCode "kp_divide", number 0xb5 +KP_Divide 0xb5 + +# evdev 99 (0x63), QKeyCode "sysrq", number 0x54 +Print 0x54 + +# evdev 100 (0x64), QKeyCode "alt_r", number 0xb8 +Alt_R 0xb8 +Meta_R 0xb8 shift + +# evdev 101 (0x65), QKeyCode "lf", number 0x5b +Linefeed 0x5b + +# evdev 102 (0x66), QKeyCode "home", number 0xc7 +Home 0xc7 + +# evdev 103 (0x67), QKeyCode "up", number 0xc8 +Up 0xc8 + +# evdev 104 (0x68), QKeyCode "pgup", number 0xc9 +Prior 0xc9 + +# evdev 105 (0x69), QKeyCode "left", number 0xcb +Left 0xcb + +# evdev 106 (0x6a), QKeyCode "right", number 0xcd +Right 0xcd + +# evdev 107 (0x6b), QKeyCode "end", number 0xcf +End 0xcf + +# evdev 108 (0x6c), QKeyCode "down", number 0xd0 +Down 0xd0 + +# evdev 109 (0x6d), QKeyCode "pgdn", number 0xd1 +Next 0xd1 + +# evdev 110 (0x6e), QKeyCode "insert", number 0xd2 +Insert 0xd2 + +# evdev 111 (0x6f), QKeyCode "delete", number 0xd3 +Delete 0xd3 + +# evdev 112 (0x70): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 113 (0x71), QKeyCode "audiomute", number 0xa0 +XF86AudioMute 0xa0 + +# evdev 114 (0x72), QKeyCode "volumedown", number 0xae +XF86AudioLowerVolume 0xae + +# evdev 115 (0x73), QKeyCode "volumeup", number 0xb0 +XF86AudioRaiseVolume 0xb0 + +# evdev 116 (0x74), QKeyCode "power", number 0xde +XF86PowerOff 0xde + +# evdev 117 (0x75), QKeyCode "kp_equals", number 0x59 +KP_Equal 0x59 + +# evdev 118 (0x76): no evdev -> QKeyCode mapping (xkb keysym plusminus) + +# evdev 119 (0x77), QKeyCode "pause", number 0xc6 +Pause 0xc6 + +# evdev 120 (0x78): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchA) + +# evdev 121 (0x79), QKeyCode "kp_comma", number 0x7e +KP_Decimal 0x7e + +# evdev 122 (0x7a): no evdev -> QKeyCode mapping (xkb keysym Hangul) + +# evdev 123 (0x7b): no evdev -> QKeyCode mapping (xkb keysym Hangul_Hanja) + +# evdev 124 (0x7c), QKeyCode "yen", number 0x7d + +# evdev 125 (0x7d), QKeyCode "meta_l", number 0xdb +Super_L 0xdb + +# evdev 126 (0x7e), QKeyCode "meta_r", number 0xdc +Super_R 0xdc + +# evdev 127 (0x7f), QKeyCode "compose", number 0xdd +Menu 0xdd + +# evdev 128 (0x80), QKeyCode "stop", number 0xe8 +Cancel 0xe8 + +# evdev 129 (0x81), QKeyCode "again", number 0x85 +Redo 0x85 + +# evdev 130 (0x82), QKeyCode "props", number 0x86 +SunProps 0x86 + +# evdev 131 (0x83), QKeyCode "undo", number 0x87 +Undo 0x87 + +# evdev 132 (0x84), QKeyCode "front", number 0x8c +SunFront 0x8c + +# evdev 133 (0x85), QKeyCode "copy", number 0xf8 +XF86Copy 0xf8 + +# evdev 134 (0x86), QKeyCode "open", number 0x64 +XF86Open 0x64 + +# evdev 135 (0x87), QKeyCode "paste", number 0x65 +XF86Paste 0x65 + +# evdev 136 (0x88), QKeyCode "find", number 0xc1 +Find 0xc1 + +# evdev 137 (0x89), QKeyCode "cut", number 0xbc +XF86Cut 0xbc + +# evdev 138 (0x8a), QKeyCode "help", number 0xf5 +Help 0xf5 + +# evdev 139 (0x8b), QKeyCode "menu", number 0x9e +XF86MenuKB 0x9e + +# evdev 140 (0x8c), QKeyCode "calculator", number 0xa1 +XF86Calculator 0xa1 + +# evdev 141 (0x8d): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 142 (0x8e), QKeyCode "sleep", number 0xdf +XF86Sleep 0xdf + +# evdev 143 (0x8f), QKeyCode "wake", number 0xe3 +XF86WakeUp 0xe3 + +# evdev 144 (0x90): no evdev -> QKeyCode mapping (xkb keysym XF86Explorer) + +# evdev 145 (0x91): no evdev -> QKeyCode mapping (xkb keysym XF86Send) + +# evdev 146 (0x92): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 147 (0x93): no evdev -> QKeyCode mapping (xkb keysym XF86Xfer) + +# evdev 148 (0x94): no evdev -> QKeyCode mapping (xkb keysym XF86Launch1) + +# evdev 149 (0x95): no evdev -> QKeyCode mapping (xkb keysym XF86Launch2) + +# evdev 150 (0x96): no evdev -> QKeyCode mapping (xkb keysym XF86WWW) + +# evdev 151 (0x97): no evdev -> QKeyCode mapping (xkb keysym XF86DOS) + +# evdev 152 (0x98): no evdev -> QKeyCode mapping (xkb keysym XF86ScreenSaver) + +# evdev 153 (0x99): no evdev -> QKeyCode mapping (xkb keysym XF86RotateWindows) + +# evdev 154 (0x9a): no evdev -> QKeyCode mapping (xkb keysym XF86TaskPane) + +# evdev 155 (0x9b), QKeyCode "mail", number 0xec +XF86Mail 0xec + +# evdev 156 (0x9c), QKeyCode "ac_bookmarks", number 0xe6 +XF86Favorites 0xe6 + +# evdev 157 (0x9d), QKeyCode "computer", number 0xeb +XF86MyComputer 0xeb + +# evdev 158 (0x9e), QKeyCode "ac_back", number 0xea +XF86Back 0xea + +# evdev 159 (0x9f), QKeyCode "ac_forward", number 0xe9 +XF86Forward 0xe9 + +# evdev 160 (0xa0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 161 (0xa1): no evdev -> QKeyCode mapping (xkb keysym XF86Eject) + +# evdev 162 (0xa2): no evdev -> QKeyCode mapping (xkb keysym XF86Eject) + +# evdev 163 (0xa3), QKeyCode "audionext", number 0x99 +XF86AudioNext 0x99 + +# evdev 164 (0xa4), QKeyCode "audioplay", number 0xa2 +XF86AudioPlay 0xa2 +XF86AudioPause 0xa2 shift + +# evdev 165 (0xa5), QKeyCode "audioprev", number 0x90 +XF86AudioPrev 0x90 + +# evdev 166 (0xa6), QKeyCode "audiostop", number 0xa4 +XF86AudioStop 0xa4 +XF86Eject 0xa4 shift + +# evdev 167 (0xa7): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRecord) + +# evdev 168 (0xa8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRewind) + +# evdev 169 (0xa9): no evdev -> QKeyCode mapping (xkb keysym XF86Phone) + +# evdev 170 (0xaa): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 171 (0xab): no evdev -> QKeyCode mapping (xkb keysym XF86Tools) + +# evdev 172 (0xac), QKeyCode "ac_home", number 0xb2 +XF86HomePage 0xb2 + +# evdev 173 (0xad), QKeyCode "ac_refresh", number 0xe7 +XF86Reload 0xe7 + +# evdev 174 (0xae): no evdev -> QKeyCode mapping (xkb keysym XF86Close) + +# evdev 175 (0xaf): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 176 (0xb0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 177 (0xb1): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollUp) + +# evdev 178 (0xb2): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollDown) + +# evdev 179 (0xb3): no evdev -> QKeyCode mapping (xkb keysym parenleft) + +# evdev 180 (0xb4): no evdev -> QKeyCode mapping (xkb keysym parenright) + +# evdev 181 (0xb5): no evdev -> QKeyCode mapping (xkb keysym XF86New) + +# evdev 182 (0xb6): no evdev -> QKeyCode mapping (xkb keysym Redo) + +# evdev 183 (0xb7): no evdev -> QKeyCode mapping (xkb keysym XF86Tools) + +# evdev 184 (0xb8): no evdev -> QKeyCode mapping (xkb keysym XF86Launch5) + +# evdev 185 (0xb9): no evdev -> QKeyCode mapping (xkb keysym XF86Launch6) + +# evdev 186 (0xba): no evdev -> QKeyCode mapping (xkb keysym XF86Launch7) + +# evdev 187 (0xbb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch8) + +# evdev 188 (0xbc): no evdev -> QKeyCode mapping (xkb keysym XF86Launch9) + +# evdev 189 (0xbd): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 190 (0xbe): no evdev -> QKeyCode mapping (xkb keysym XF86AudioMicMute) + +# evdev 191 (0xbf): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadToggle) + +# evdev 192 (0xc0): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOn) + +# evdev 193 (0xc1): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOff) + +# evdev 194 (0xc2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 195 (0xc3): no evdev -> QKeyCode mapping (xkb keysym Mode_switch) + +# evdev 196 (0xc4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 197 (0xc5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 198 (0xc6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 199 (0xc7): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 200 (0xc8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay) + +# evdev 201 (0xc9): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPause) + +# evdev 202 (0xca): no evdev -> QKeyCode mapping (xkb keysym XF86Launch3) + +# evdev 203 (0xcb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch4) + +# evdev 204 (0xcc): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchB) + +# evdev 205 (0xcd): no evdev -> QKeyCode mapping (xkb keysym XF86Suspend) + +# evdev 206 (0xce): no evdev -> QKeyCode mapping (xkb keysym XF86Close) + +# evdev 207 (0xcf): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay) + +# evdev 208 (0xd0): no evdev -> QKeyCode mapping (xkb keysym XF86AudioForward) + +# evdev 209 (0xd1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 210 (0xd2): no evdev -> QKeyCode mapping (xkb keysym Print) + +# evdev 211 (0xd3): no evdev -> QKeyCode mapping (xkb keysym ISO_Next_Group) + +# evdev 212 (0xd4): no evdev -> QKeyCode mapping (xkb keysym XF86WebCam) + +# evdev 213 (0xd5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 214 (0xd6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 215 (0xd7): no evdev -> QKeyCode mapping (xkb keysym XF86Mail) + +# evdev 216 (0xd8): no evdev -> QKeyCode mapping (xkb keysym XF86Messenger) + +# evdev 217 (0xd9): no evdev -> QKeyCode mapping (xkb keysym XF86Search) + +# evdev 218 (0xda): no evdev -> QKeyCode mapping (xkb keysym XF86Go) + +# evdev 219 (0xdb): no evdev -> QKeyCode mapping (xkb keysym XF86Finance) + +# evdev 220 (0xdc): no evdev -> QKeyCode mapping (xkb keysym XF86Game) + +# evdev 221 (0xdd): no evdev -> QKeyCode mapping (xkb keysym XF86Shop) + +# evdev 222 (0xde): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 223 (0xdf): no evdev -> QKeyCode mapping (xkb keysym Cancel) + +# evdev 224 (0xe0): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessDown) + +# evdev 225 (0xe1): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessUp) + +# evdev 226 (0xe2), QKeyCode "mediaselect", number 0xed +XF86AudioMedia 0xed + +# evdev 227 (0xe3): no evdev -> QKeyCode mapping (xkb keysym XF86Display) + +# evdev 228 (0xe4): no evdev -> QKeyCode mapping (xkb keysym XF86KbdLightOnOff) + +# evdev 229 (0xe5): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessDown) + +# evdev 230 (0xe6): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessUp) + +# evdev 231 (0xe7): no evdev -> QKeyCode mapping (xkb keysym XF86Send) + +# evdev 232 (0xe8): no evdev -> QKeyCode mapping (xkb keysym XF86Reply) + +# evdev 233 (0xe9): no evdev -> QKeyCode mapping (xkb keysym XF86MailForward) + +# evdev 234 (0xea): no evdev -> QKeyCode mapping (xkb keysym XF86Save) + +# evdev 235 (0xeb): no evdev -> QKeyCode mapping (xkb keysym XF86Documents) + +# evdev 236 (0xec): no evdev -> QKeyCode mapping (xkb keysym XF86Battery) + +# evdev 237 (0xed): no evdev -> QKeyCode mapping (xkb keysym XF86Bluetooth) + +# evdev 238 (0xee): no evdev -> QKeyCode mapping (xkb keysym XF86WLAN) + +# evdev 239 (0xef): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 240 (0xf0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 241 (0xf1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 242 (0xf2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 243 (0xf3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 244 (0xf4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 245 (0xf5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 246 (0xf6): no evdev -> QKeyCode mapping (xkb keysym Invalid) + +# evdev 247 (0xf7): no evdev -> QKeyCode mapping (xkb keysym Invalid) + +# +# quirks section start +# +# Sometimes multiple keysyms map to the same keycodes. +# The keycode -> keysym lookup finds only one of the +# keysyms. So append them here. +# + +Print 0x54 +Sys_Req 0x54 +Execute 0x54 +KP_Decimal 0x53 numlock +KP_Separator 0x53 numlock +Alt_R 0xb8 +ISO_Level3_Shift 0xb8 +Mode_switch 0xb8 + +# quirks section end diff --git a/app/src/main/assets/roms/keymaps/fi b/app/src/main/assets/roms/keymaps/fi new file mode 100644 index 0000000..8167494 --- /dev/null +++ b/app/src/main/assets/roms/keymaps/fi @@ -0,0 +1,816 @@ +# +# generated by qemu-keymap +# model : pc105 +# layout : fi +# variant : - +# options : - + +# name: "Finnish" + +# modifiers +# 0: Shift +# 1: Lock +# 2: Control +# 3: Mod1 +# 4: Mod2 +# 5: Mod3 +# 6: Mod4 +# 7: Mod5 +# 8: NumLock +# 9: Alt +# 10: LevelThree +# 11: LAlt +# 12: RAlt +# 13: RControl +# 14: LControl +# 15: ScrollLock +# 16: LevelFive +# 17: AltGr +# 18: Meta +# 19: Super +# 20: Hyper + +# evdev 1 (0x1), QKeyCode "esc", number 0x1 +Escape 0x01 + +# evdev 2 (0x2), QKeyCode "1", number 0x2 +1 0x02 +exclam 0x02 shift +exclamdown 0x02 shift altgr + +# evdev 3 (0x3), QKeyCode "2", number 0x3 +2 0x03 +quotedbl 0x03 shift +at 0x03 altgr +rightdoublequotemark 0x03 shift altgr + +# evdev 4 (0x4), QKeyCode "3", number 0x4 +3 0x04 +numbersign 0x04 shift +sterling 0x04 altgr +guillemotright 0x04 shift altgr + +# evdev 5 (0x5), QKeyCode "4", number 0x5 +4 0x05 +currency 0x05 shift +dollar 0x05 altgr +guillemotleft 0x05 shift altgr + +# evdev 6 (0x6), QKeyCode "5", number 0x6 +5 0x06 +percent 0x06 shift +permille 0x06 altgr +leftdoublequotemark 0x06 shift altgr + +# evdev 7 (0x7), QKeyCode "6", number 0x7 +6 0x07 +ampersand 0x07 shift +singlelowquotemark 0x07 altgr +doublelowquotemark 0x07 shift altgr + +# evdev 8 (0x8), QKeyCode "7", number 0x8 +7 0x08 +slash 0x08 shift +braceleft 0x08 altgr + +# evdev 9 (0x9), QKeyCode "8", number 0x9 +8 0x09 +parenleft 0x09 shift +bracketleft 0x09 altgr +less 0x09 shift altgr + +# evdev 10 (0xa), QKeyCode "9", number 0xa +9 0x0a +parenright 0x0a shift +bracketright 0x0a altgr +greater 0x0a shift altgr + +# evdev 11 (0xb), QKeyCode "0", number 0xb +0 0x0b +equal 0x0b shift +braceright 0x0b altgr +degree 0x0b shift altgr + +# evdev 12 (0xc), QKeyCode "minus", number 0xc +plus 0x0c +question 0x0c shift +backslash 0x0c altgr +questiondown 0x0c shift altgr + +# evdev 13 (0xd), QKeyCode "equal", number 0xd +dead_acute 0x0d +dead_grave 0x0d shift +dead_cedilla 0x0d altgr +dead_ogonek 0x0d shift altgr + +# evdev 14 (0xe), QKeyCode "backspace", number 0xe +BackSpace 0x0e + +# evdev 15 (0xf), QKeyCode "tab", number 0xf +Tab 0x0f +ISO_Left_Tab 0x0f shift + +# evdev 16 (0x10), QKeyCode "q", number 0x10 +q 0x10 +Q 0x10 shift + +# evdev 17 (0x11), QKeyCode "w", number 0x11 +w 0x11 +W 0x11 shift + +# evdev 18 (0x12), QKeyCode "e", number 0x12 +e 0x12 +E 0x12 shift +EuroSign 0x12 altgr + +# evdev 19 (0x13), QKeyCode "r", number 0x13 +r 0x13 +R 0x13 shift + +# evdev 20 (0x14), QKeyCode "t", number 0x14 +t 0x14 +T 0x14 shift +thorn 0x14 altgr +THORN 0x14 shift altgr + +# evdev 21 (0x15), QKeyCode "y", number 0x15 +y 0x15 +Y 0x15 shift + +# evdev 22 (0x16), QKeyCode "u", number 0x16 +u 0x16 +U 0x16 shift + +# evdev 23 (0x17), QKeyCode "i", number 0x17 +i 0x17 +I 0x17 shift +idotless 0x17 altgr +bar 0x17 shift altgr + +# evdev 24 (0x18), QKeyCode "o", number 0x18 +o 0x18 +O 0x18 shift +oe 0x18 altgr +OE 0x18 shift altgr + +# evdev 25 (0x19), QKeyCode "p", number 0x19 +p 0x19 +P 0x19 shift +dead_horn 0x19 altgr +dead_hook 0x19 shift altgr + +# evdev 26 (0x1a), QKeyCode "bracket_left", number 0x1a +aring 0x1a +Aring 0x1a shift +dead_doubleacute 0x1a altgr +dead_abovering 0x1a shift altgr + +# evdev 27 (0x1b), QKeyCode "bracket_right", number 0x1b +dead_diaeresis 0x1b +dead_circumflex 0x1b shift +dead_tilde 0x1b altgr +dead_macron 0x1b shift altgr + +# evdev 28 (0x1c), QKeyCode "ret", number 0x1c +Return 0x1c + +# evdev 29 (0x1d), QKeyCode "ctrl", number 0x1d +Control_L 0x1d + +# evdev 30 (0x1e), QKeyCode "a", number 0x1e +a 0x1e +A 0x1e shift +schwa 0x1e altgr +SCHWA 0x1e shift altgr + +# evdev 31 (0x1f), QKeyCode "s", number 0x1f +s 0x1f +S 0x1f shift +ssharp 0x1f altgr + +# evdev 32 (0x20), QKeyCode "d", number 0x20 +d 0x20 +D 0x20 shift +eth 0x20 altgr +ETH 0x20 shift altgr + +# evdev 33 (0x21), QKeyCode "f", number 0x21 +f 0x21 +F 0x21 shift + +# evdev 34 (0x22), QKeyCode "g", number 0x22 +g 0x22 +G 0x22 shift + +# evdev 35 (0x23), QKeyCode "h", number 0x23 +h 0x23 +H 0x23 shift + +# evdev 36 (0x24), QKeyCode "j", number 0x24 +j 0x24 +J 0x24 shift + +# evdev 37 (0x25), QKeyCode "k", number 0x25 +k 0x25 +K 0x25 shift +kra 0x25 altgr + +# evdev 38 (0x26), QKeyCode "l", number 0x26 +l 0x26 +L 0x26 shift +dead_stroke 0x26 altgr + +# evdev 39 (0x27), QKeyCode "semicolon", number 0x27 +odiaeresis 0x27 +Odiaeresis 0x27 shift +oslash 0x27 altgr +Oslash 0x27 shift altgr + +# evdev 40 (0x28), QKeyCode "apostrophe", number 0x28 +adiaeresis 0x28 +Adiaeresis 0x28 shift +ae 0x28 altgr +AE 0x28 shift altgr + +# evdev 41 (0x29), QKeyCode "grave_accent", number 0x29 +section 0x29 +onehalf 0x29 shift +dead_stroke 0x29 altgr + +# evdev 42 (0x2a), QKeyCode "shift", number 0x2a +Shift_L 0x2a + +# evdev 43 (0x2b), QKeyCode "backslash", number 0x2b +apostrophe 0x2b +asterisk 0x2b shift +dead_caron 0x2b altgr +dead_breve 0x2b shift altgr + +# evdev 44 (0x2c), QKeyCode "z", number 0x2c +z 0x2c +Z 0x2c shift +ezh 0x2c altgr +EZH 0x2c shift altgr + +# evdev 45 (0x2d), QKeyCode "x", number 0x2d +x 0x2d +X 0x2d shift +multiply 0x2d altgr +periodcentered 0x2d shift altgr + +# evdev 46 (0x2e), QKeyCode "c", number 0x2e +c 0x2e +C 0x2e shift + +# evdev 47 (0x2f), QKeyCode "v", number 0x2f +v 0x2f +V 0x2f shift + +# evdev 48 (0x30), QKeyCode "b", number 0x30 +b 0x30 +B 0x30 shift + +# evdev 49 (0x31), QKeyCode "n", number 0x31 +n 0x31 +N 0x31 shift +eng 0x31 altgr +ENG 0x31 shift altgr + +# evdev 50 (0x32), QKeyCode "m", number 0x32 +m 0x32 +M 0x32 shift +mu 0x32 altgr +emdash 0x32 shift altgr + +# evdev 51 (0x33), QKeyCode "comma", number 0x33 +comma 0x33 +semicolon 0x33 shift +rightsinglequotemark 0x33 altgr +leftsinglequotemark 0x33 shift altgr + +# evdev 52 (0x34), QKeyCode "dot", number 0x34 +period 0x34 +colon 0x34 shift +dead_belowdot 0x34 altgr +dead_abovedot 0x34 shift altgr + +# evdev 53 (0x35), QKeyCode "slash", number 0x35 +minus 0x35 +underscore 0x35 shift +endash 0x35 altgr +dead_belowcomma 0x35 shift altgr + +# evdev 54 (0x36), QKeyCode "shift_r", number 0x36 +Shift_R 0x36 + +# evdev 55 (0x37), QKeyCode "kp_multiply", number 0x37 +KP_Multiply 0x37 + +# evdev 56 (0x38), QKeyCode "alt", number 0x38 +Alt_L 0x38 +Meta_L 0x38 shift + +# evdev 57 (0x39), QKeyCode "spc", number 0x39 +space 0x39 +nobreakspace 0x39 altgr + +# evdev 58 (0x3a), QKeyCode "caps_lock", number 0x3a +Caps_Lock 0x3a + +# evdev 59 (0x3b), QKeyCode "f1", number 0x3b +F1 0x3b + +# evdev 60 (0x3c), QKeyCode "f2", number 0x3c +F2 0x3c + +# evdev 61 (0x3d), QKeyCode "f3", number 0x3d +F3 0x3d + +# evdev 62 (0x3e), QKeyCode "f4", number 0x3e +F4 0x3e + +# evdev 63 (0x3f), QKeyCode "f5", number 0x3f +F5 0x3f + +# evdev 64 (0x40), QKeyCode "f6", number 0x40 +F6 0x40 + +# evdev 65 (0x41), QKeyCode "f7", number 0x41 +F7 0x41 + +# evdev 66 (0x42), QKeyCode "f8", number 0x42 +F8 0x42 + +# evdev 67 (0x43), QKeyCode "f9", number 0x43 +F9 0x43 + +# evdev 68 (0x44), QKeyCode "f10", number 0x44 +F10 0x44 + +# evdev 69 (0x45), QKeyCode "num_lock", number 0x45 +Num_Lock 0x45 + +# evdev 70 (0x46), QKeyCode "scroll_lock", number 0x46 +Scroll_Lock 0x46 + +# evdev 71 (0x47), QKeyCode "kp_7", number 0x47 +KP_Home 0x47 +KP_7 0x47 numlock + +# evdev 72 (0x48), QKeyCode "kp_8", number 0x48 +KP_Up 0x48 +KP_8 0x48 numlock + +# evdev 73 (0x49), QKeyCode "kp_9", number 0x49 +KP_Prior 0x49 +KP_9 0x49 numlock + +# evdev 74 (0x4a), QKeyCode "kp_subtract", number 0x4a +KP_Subtract 0x4a + +# evdev 75 (0x4b), QKeyCode "kp_4", number 0x4b +KP_Left 0x4b +KP_4 0x4b numlock + +# evdev 76 (0x4c), QKeyCode "kp_5", number 0x4c +KP_Begin 0x4c +KP_5 0x4c numlock + +# evdev 77 (0x4d), QKeyCode "kp_6", number 0x4d +KP_Right 0x4d +KP_6 0x4d numlock + +# evdev 78 (0x4e), QKeyCode "kp_add", number 0x4e +KP_Add 0x4e + +# evdev 79 (0x4f), QKeyCode "kp_1", number 0x4f +KP_End 0x4f +KP_1 0x4f numlock + +# evdev 80 (0x50), QKeyCode "kp_2", number 0x50 +KP_Down 0x50 +KP_2 0x50 numlock + +# evdev 81 (0x51), QKeyCode "kp_3", number 0x51 +KP_Next 0x51 +KP_3 0x51 numlock + +# evdev 82 (0x52), QKeyCode "kp_0", number 0x52 +KP_Insert 0x52 +KP_0 0x52 numlock + +# evdev 83 (0x53), QKeyCode "kp_decimal", number 0x53 +KP_Delete 0x53 +KP_Separator 0x53 numlock + +# evdev 84 (0x54): no evdev -> QKeyCode mapping (xkb keysym ISO_Level3_Shift) + +# evdev 85 (0x55): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 86 (0x56), QKeyCode "less", number 0x56 +less 0x56 +greater 0x56 shift +bar 0x56 altgr +brokenbar 0x56 shift altgr + +# evdev 87 (0x57), QKeyCode "f11", number 0x57 +F11 0x57 + +# evdev 88 (0x58), QKeyCode "f12", number 0x58 +F12 0x58 + +# evdev 89 (0x59), QKeyCode "ro", number 0x73 + +# evdev 90 (0x5a): no evdev -> QKeyCode mapping (xkb keysym Katakana) + +# evdev 91 (0x5b), QKeyCode "hiragana", number 0x77 +Hiragana 0x77 + +# evdev 92 (0x5c), QKeyCode "henkan", number 0x79 +Henkan_Mode 0x79 + +# evdev 93 (0x5d), QKeyCode "katakanahiragana", number 0x70 +Hiragana_Katakana 0x70 + +# evdev 94 (0x5e), QKeyCode "muhenkan", number 0x7b +Muhenkan 0x7b + +# evdev 95 (0x5f): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 96 (0x60), QKeyCode "kp_enter", number 0x9c +KP_Enter 0x9c + +# evdev 97 (0x61), QKeyCode "ctrl_r", number 0x9d +Control_R 0x9d + +# evdev 98 (0x62), QKeyCode "kp_divide", number 0xb5 +KP_Divide 0xb5 + +# evdev 99 (0x63), QKeyCode "sysrq", number 0x54 +Print 0x54 + +# evdev 100 (0x64), QKeyCode "alt_r", number 0xb8 +ISO_Level3_Shift 0xb8 + +# evdev 101 (0x65), QKeyCode "lf", number 0x5b +Linefeed 0x5b + +# evdev 102 (0x66), QKeyCode "home", number 0xc7 +Home 0xc7 + +# evdev 103 (0x67), QKeyCode "up", number 0xc8 +Up 0xc8 + +# evdev 104 (0x68), QKeyCode "pgup", number 0xc9 +Prior 0xc9 + +# evdev 105 (0x69), QKeyCode "left", number 0xcb +Left 0xcb + +# evdev 106 (0x6a), QKeyCode "right", number 0xcd +Right 0xcd + +# evdev 107 (0x6b), QKeyCode "end", number 0xcf +End 0xcf + +# evdev 108 (0x6c), QKeyCode "down", number 0xd0 +Down 0xd0 + +# evdev 109 (0x6d), QKeyCode "pgdn", number 0xd1 +Next 0xd1 + +# evdev 110 (0x6e), QKeyCode "insert", number 0xd2 +Insert 0xd2 + +# evdev 111 (0x6f), QKeyCode "delete", number 0xd3 +Delete 0xd3 + +# evdev 112 (0x70): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 113 (0x71), QKeyCode "audiomute", number 0xa0 +XF86AudioMute 0xa0 + +# evdev 114 (0x72), QKeyCode "volumedown", number 0xae +XF86AudioLowerVolume 0xae + +# evdev 115 (0x73), QKeyCode "volumeup", number 0xb0 +XF86AudioRaiseVolume 0xb0 + +# evdev 116 (0x74), QKeyCode "power", number 0xde +XF86PowerOff 0xde + +# evdev 117 (0x75), QKeyCode "kp_equals", number 0x59 +KP_Equal 0x59 + +# evdev 118 (0x76): no evdev -> QKeyCode mapping (xkb keysym plusminus) + +# evdev 119 (0x77), QKeyCode "pause", number 0xc6 +Pause 0xc6 + +# evdev 120 (0x78): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchA) + +# evdev 121 (0x79), QKeyCode "kp_comma", number 0x7e +KP_Decimal 0x7e + +# evdev 122 (0x7a): no evdev -> QKeyCode mapping (xkb keysym Hangul) + +# evdev 123 (0x7b): no evdev -> QKeyCode mapping (xkb keysym Hangul_Hanja) + +# evdev 124 (0x7c), QKeyCode "yen", number 0x7d + +# evdev 125 (0x7d), QKeyCode "meta_l", number 0xdb +Super_L 0xdb + +# evdev 126 (0x7e), QKeyCode "meta_r", number 0xdc +Super_R 0xdc + +# evdev 127 (0x7f), QKeyCode "compose", number 0xdd +Menu 0xdd + +# evdev 128 (0x80), QKeyCode "stop", number 0xe8 +Cancel 0xe8 + +# evdev 129 (0x81), QKeyCode "again", number 0x85 +Redo 0x85 + +# evdev 130 (0x82), QKeyCode "props", number 0x86 +SunProps 0x86 + +# evdev 131 (0x83), QKeyCode "undo", number 0x87 +Undo 0x87 + +# evdev 132 (0x84), QKeyCode "front", number 0x8c +SunFront 0x8c + +# evdev 133 (0x85), QKeyCode "copy", number 0xf8 +XF86Copy 0xf8 + +# evdev 134 (0x86), QKeyCode "open", number 0x64 +XF86Open 0x64 + +# evdev 135 (0x87), QKeyCode "paste", number 0x65 +XF86Paste 0x65 + +# evdev 136 (0x88), QKeyCode "find", number 0xc1 +Find 0xc1 + +# evdev 137 (0x89), QKeyCode "cut", number 0xbc +XF86Cut 0xbc + +# evdev 138 (0x8a), QKeyCode "help", number 0xf5 +Help 0xf5 + +# evdev 139 (0x8b), QKeyCode "menu", number 0x9e +XF86MenuKB 0x9e + +# evdev 140 (0x8c), QKeyCode "calculator", number 0xa1 +XF86Calculator 0xa1 + +# evdev 141 (0x8d): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 142 (0x8e), QKeyCode "sleep", number 0xdf +XF86Sleep 0xdf + +# evdev 143 (0x8f), QKeyCode "wake", number 0xe3 +XF86WakeUp 0xe3 + +# evdev 144 (0x90): no evdev -> QKeyCode mapping (xkb keysym XF86Explorer) + +# evdev 145 (0x91): no evdev -> QKeyCode mapping (xkb keysym XF86Send) + +# evdev 146 (0x92): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 147 (0x93): no evdev -> QKeyCode mapping (xkb keysym XF86Xfer) + +# evdev 148 (0x94): no evdev -> QKeyCode mapping (xkb keysym XF86Launch1) + +# evdev 149 (0x95): no evdev -> QKeyCode mapping (xkb keysym XF86Launch2) + +# evdev 150 (0x96): no evdev -> QKeyCode mapping (xkb keysym XF86WWW) + +# evdev 151 (0x97): no evdev -> QKeyCode mapping (xkb keysym XF86DOS) + +# evdev 152 (0x98): no evdev -> QKeyCode mapping (xkb keysym XF86ScreenSaver) + +# evdev 153 (0x99): no evdev -> QKeyCode mapping (xkb keysym XF86RotateWindows) + +# evdev 154 (0x9a): no evdev -> QKeyCode mapping (xkb keysym XF86TaskPane) + +# evdev 155 (0x9b), QKeyCode "mail", number 0xec +XF86Mail 0xec + +# evdev 156 (0x9c), QKeyCode "ac_bookmarks", number 0xe6 +XF86Favorites 0xe6 + +# evdev 157 (0x9d), QKeyCode "computer", number 0xeb +XF86MyComputer 0xeb + +# evdev 158 (0x9e), QKeyCode "ac_back", number 0xea +XF86Back 0xea + +# evdev 159 (0x9f), QKeyCode "ac_forward", number 0xe9 +XF86Forward 0xe9 + +# evdev 160 (0xa0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 161 (0xa1): no evdev -> QKeyCode mapping (xkb keysym XF86Eject) + +# evdev 162 (0xa2): no evdev -> QKeyCode mapping (xkb keysym XF86Eject) + +# evdev 163 (0xa3), QKeyCode "audionext", number 0x99 +XF86AudioNext 0x99 + +# evdev 164 (0xa4), QKeyCode "audioplay", number 0xa2 +XF86AudioPlay 0xa2 +XF86AudioPause 0xa2 shift + +# evdev 165 (0xa5), QKeyCode "audioprev", number 0x90 +XF86AudioPrev 0x90 + +# evdev 166 (0xa6), QKeyCode "audiostop", number 0xa4 +XF86AudioStop 0xa4 +XF86Eject 0xa4 shift + +# evdev 167 (0xa7): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRecord) + +# evdev 168 (0xa8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRewind) + +# evdev 169 (0xa9): no evdev -> QKeyCode mapping (xkb keysym XF86Phone) + +# evdev 170 (0xaa): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 171 (0xab): no evdev -> QKeyCode mapping (xkb keysym XF86Tools) + +# evdev 172 (0xac), QKeyCode "ac_home", number 0xb2 +XF86HomePage 0xb2 + +# evdev 173 (0xad), QKeyCode "ac_refresh", number 0xe7 +XF86Reload 0xe7 + +# evdev 174 (0xae): no evdev -> QKeyCode mapping (xkb keysym XF86Close) + +# evdev 175 (0xaf): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 176 (0xb0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 177 (0xb1): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollUp) + +# evdev 178 (0xb2): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollDown) + +# evdev 179 (0xb3): no evdev -> QKeyCode mapping (xkb keysym parenleft) + +# evdev 180 (0xb4): no evdev -> QKeyCode mapping (xkb keysym parenright) + +# evdev 181 (0xb5): no evdev -> QKeyCode mapping (xkb keysym XF86New) + +# evdev 182 (0xb6): no evdev -> QKeyCode mapping (xkb keysym Redo) + +# evdev 183 (0xb7): no evdev -> QKeyCode mapping (xkb keysym XF86Tools) + +# evdev 184 (0xb8): no evdev -> QKeyCode mapping (xkb keysym XF86Launch5) + +# evdev 185 (0xb9): no evdev -> QKeyCode mapping (xkb keysym XF86Launch6) + +# evdev 186 (0xba): no evdev -> QKeyCode mapping (xkb keysym XF86Launch7) + +# evdev 187 (0xbb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch8) + +# evdev 188 (0xbc): no evdev -> QKeyCode mapping (xkb keysym XF86Launch9) + +# evdev 189 (0xbd): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 190 (0xbe): no evdev -> QKeyCode mapping (xkb keysym XF86AudioMicMute) + +# evdev 191 (0xbf): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadToggle) + +# evdev 192 (0xc0): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOn) + +# evdev 193 (0xc1): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOff) + +# evdev 194 (0xc2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 195 (0xc3): no evdev -> QKeyCode mapping (xkb keysym Mode_switch) + +# evdev 196 (0xc4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 197 (0xc5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 198 (0xc6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 199 (0xc7): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 200 (0xc8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay) + +# evdev 201 (0xc9): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPause) + +# evdev 202 (0xca): no evdev -> QKeyCode mapping (xkb keysym XF86Launch3) + +# evdev 203 (0xcb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch4) + +# evdev 204 (0xcc): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchB) + +# evdev 205 (0xcd): no evdev -> QKeyCode mapping (xkb keysym XF86Suspend) + +# evdev 206 (0xce): no evdev -> QKeyCode mapping (xkb keysym XF86Close) + +# evdev 207 (0xcf): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay) + +# evdev 208 (0xd0): no evdev -> QKeyCode mapping (xkb keysym XF86AudioForward) + +# evdev 209 (0xd1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 210 (0xd2): no evdev -> QKeyCode mapping (xkb keysym Print) + +# evdev 211 (0xd3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 212 (0xd4): no evdev -> QKeyCode mapping (xkb keysym XF86WebCam) + +# evdev 213 (0xd5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 214 (0xd6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 215 (0xd7): no evdev -> QKeyCode mapping (xkb keysym XF86Mail) + +# evdev 216 (0xd8): no evdev -> QKeyCode mapping (xkb keysym XF86Messenger) + +# evdev 217 (0xd9): no evdev -> QKeyCode mapping (xkb keysym XF86Search) + +# evdev 218 (0xda): no evdev -> QKeyCode mapping (xkb keysym XF86Go) + +# evdev 219 (0xdb): no evdev -> QKeyCode mapping (xkb keysym XF86Finance) + +# evdev 220 (0xdc): no evdev -> QKeyCode mapping (xkb keysym XF86Game) + +# evdev 221 (0xdd): no evdev -> QKeyCode mapping (xkb keysym XF86Shop) + +# evdev 222 (0xde): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 223 (0xdf): no evdev -> QKeyCode mapping (xkb keysym Cancel) + +# evdev 224 (0xe0): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessDown) + +# evdev 225 (0xe1): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessUp) + +# evdev 226 (0xe2), QKeyCode "mediaselect", number 0xed +XF86AudioMedia 0xed + +# evdev 227 (0xe3): no evdev -> QKeyCode mapping (xkb keysym XF86Display) + +# evdev 228 (0xe4): no evdev -> QKeyCode mapping (xkb keysym XF86KbdLightOnOff) + +# evdev 229 (0xe5): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessDown) + +# evdev 230 (0xe6): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessUp) + +# evdev 231 (0xe7): no evdev -> QKeyCode mapping (xkb keysym XF86Send) + +# evdev 232 (0xe8): no evdev -> QKeyCode mapping (xkb keysym XF86Reply) + +# evdev 233 (0xe9): no evdev -> QKeyCode mapping (xkb keysym XF86MailForward) + +# evdev 234 (0xea): no evdev -> QKeyCode mapping (xkb keysym XF86Save) + +# evdev 235 (0xeb): no evdev -> QKeyCode mapping (xkb keysym XF86Documents) + +# evdev 236 (0xec): no evdev -> QKeyCode mapping (xkb keysym XF86Battery) + +# evdev 237 (0xed): no evdev -> QKeyCode mapping (xkb keysym XF86Bluetooth) + +# evdev 238 (0xee): no evdev -> QKeyCode mapping (xkb keysym XF86WLAN) + +# evdev 239 (0xef): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 240 (0xf0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 241 (0xf1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 242 (0xf2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 243 (0xf3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 244 (0xf4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 245 (0xf5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 246 (0xf6): no evdev -> QKeyCode mapping (xkb keysym Invalid) + +# evdev 247 (0xf7): no evdev -> QKeyCode mapping (xkb keysym Invalid) + +# +# quirks section start +# +# Sometimes multiple keysyms map to the same keycodes. +# The keycode -> keysym lookup finds only one of the +# keysyms. So append them here. +# + +Print 0x54 +Sys_Req 0x54 +Execute 0x54 +KP_Decimal 0x53 numlock +KP_Separator 0x53 numlock +Alt_R 0xb8 +ISO_Level3_Shift 0xb8 +Mode_switch 0xb8 + +# quirks section end diff --git a/app/src/main/assets/roms/keymaps/fo b/app/src/main/assets/roms/keymaps/fo new file mode 100644 index 0000000..8bb6f97 --- /dev/null +++ b/app/src/main/assets/roms/keymaps/fo @@ -0,0 +1,843 @@ +# +# generated by qemu-keymap +# model : pc105 +# layout : fo +# variant : - +# options : - + +# name: "Faroese" + +# modifiers +# 0: Shift +# 1: Lock +# 2: Control +# 3: Mod1 +# 4: Mod2 +# 5: Mod3 +# 6: Mod4 +# 7: Mod5 +# 8: NumLock +# 9: Alt +# 10: LevelThree +# 11: LAlt +# 12: RAlt +# 13: RControl +# 14: LControl +# 15: ScrollLock +# 16: LevelFive +# 17: AltGr +# 18: Meta +# 19: Super +# 20: Hyper + +# evdev 1 (0x1), QKeyCode "esc", number 0x1 +Escape 0x01 + +# evdev 2 (0x2), QKeyCode "1", number 0x2 +1 0x02 +exclam 0x02 shift +exclamdown 0x02 altgr +onesuperior 0x02 shift altgr + +# evdev 3 (0x3), QKeyCode "2", number 0x3 +2 0x03 +quotedbl 0x03 shift +at 0x03 altgr +twosuperior 0x03 shift altgr + +# evdev 4 (0x4), QKeyCode "3", number 0x4 +3 0x04 +numbersign 0x04 shift +sterling 0x04 altgr +threesuperior 0x04 shift altgr + +# evdev 5 (0x5), QKeyCode "4", number 0x5 +4 0x05 +currency 0x05 shift +dollar 0x05 altgr +onequarter 0x05 shift altgr + +# evdev 6 (0x6), QKeyCode "5", number 0x6 +5 0x06 +percent 0x06 shift +onehalf 0x06 altgr +cent 0x06 shift altgr + +# evdev 7 (0x7), QKeyCode "6", number 0x7 +6 0x07 +ampersand 0x07 shift +yen 0x07 altgr +fiveeighths 0x07 shift altgr + +# evdev 8 (0x8), QKeyCode "7", number 0x8 +7 0x08 +slash 0x08 shift +braceleft 0x08 altgr +division 0x08 shift altgr + +# evdev 9 (0x9), QKeyCode "8", number 0x9 +8 0x09 +parenleft 0x09 shift +bracketleft 0x09 altgr +guillemotleft 0x09 shift altgr + +# evdev 10 (0xa), QKeyCode "9", number 0xa +9 0x0a +parenright 0x0a shift +bracketright 0x0a altgr +guillemotright 0x0a shift altgr + +# evdev 11 (0xb), QKeyCode "0", number 0xb +0 0x0b +equal 0x0b shift +braceright 0x0b altgr +degree 0x0b shift altgr + +# evdev 12 (0xc), QKeyCode "minus", number 0xc +plus 0x0c +question 0x0c shift +plusminus 0x0c altgr +questiondown 0x0c shift altgr + +# evdev 13 (0xd), QKeyCode "equal", number 0xd +dead_acute 0x0d +dead_grave 0x0d shift +bar 0x0d altgr +brokenbar 0x0d shift altgr + +# evdev 14 (0xe), QKeyCode "backspace", number 0xe +BackSpace 0x0e + +# evdev 15 (0xf), QKeyCode "tab", number 0xf +Tab 0x0f +ISO_Left_Tab 0x0f shift + +# evdev 16 (0x10), QKeyCode "q", number 0x10 +q 0x10 +Q 0x10 shift +at 0x10 altgr +Greek_OMEGA 0x10 shift altgr + +# evdev 17 (0x11), QKeyCode "w", number 0x11 +w 0x11 +W 0x11 shift +lstroke 0x11 altgr +Lstroke 0x11 shift altgr + +# evdev 18 (0x12), QKeyCode "e", number 0x12 +e 0x12 +E 0x12 shift +EuroSign 0x12 altgr +cent 0x12 shift altgr + +# evdev 19 (0x13), QKeyCode "r", number 0x13 +r 0x13 +R 0x13 shift +registered 0x13 altgr + +# evdev 20 (0x14), QKeyCode "t", number 0x14 +t 0x14 +T 0x14 shift +thorn 0x14 altgr +THORN 0x14 shift altgr + +# evdev 21 (0x15), QKeyCode "y", number 0x15 +y 0x15 +Y 0x15 shift +leftarrow 0x15 altgr +yen 0x15 shift altgr + +# evdev 22 (0x16), QKeyCode "u", number 0x16 +u 0x16 +U 0x16 shift +downarrow 0x16 altgr +uparrow 0x16 shift altgr + +# evdev 23 (0x17), QKeyCode "i", number 0x17 +i 0x17 +I 0x17 shift +rightarrow 0x17 altgr +idotless 0x17 shift altgr + +# evdev 24 (0x18), QKeyCode "o", number 0x18 +o 0x18 +O 0x18 shift +oe 0x18 altgr +OE 0x18 shift altgr + +# evdev 25 (0x19), QKeyCode "p", number 0x19 +p 0x19 +P 0x19 shift +thorn 0x19 altgr +THORN 0x19 shift altgr + +# evdev 26 (0x1a), QKeyCode "bracket_left", number 0x1a +aring 0x1a +Aring 0x1a shift +dead_diaeresis 0x1a altgr +dead_circumflex 0x1a shift altgr + +# evdev 27 (0x1b), QKeyCode "bracket_right", number 0x1b +eth 0x1b +ETH 0x1b shift +dead_tilde 0x1b altgr +dead_caron 0x1b shift altgr + +# evdev 28 (0x1c), QKeyCode "ret", number 0x1c +Return 0x1c + +# evdev 29 (0x1d), QKeyCode "ctrl", number 0x1d +Control_L 0x1d + +# evdev 30 (0x1e), QKeyCode "a", number 0x1e +a 0x1e +A 0x1e shift +ordfeminine 0x1e altgr +masculine 0x1e shift altgr + +# evdev 31 (0x1f), QKeyCode "s", number 0x1f +s 0x1f +S 0x1f shift +ssharp 0x1f altgr +section 0x1f shift altgr + +# evdev 32 (0x20), QKeyCode "d", number 0x20 +d 0x20 +D 0x20 shift +eth 0x20 altgr +ETH 0x20 shift altgr + +# evdev 33 (0x21), QKeyCode "f", number 0x21 +f 0x21 +F 0x21 shift +dstroke 0x21 altgr +ordfeminine 0x21 shift altgr + +# evdev 34 (0x22), QKeyCode "g", number 0x22 +g 0x22 +G 0x22 shift +eng 0x22 altgr +ENG 0x22 shift altgr + +# evdev 35 (0x23), QKeyCode "h", number 0x23 +h 0x23 +H 0x23 shift +hstroke 0x23 altgr +Hstroke 0x23 shift altgr + +# evdev 36 (0x24), QKeyCode "j", number 0x24 +j 0x24 +J 0x24 shift +dead_hook 0x24 altgr +dead_horn 0x24 shift altgr + +# evdev 37 (0x25), QKeyCode "k", number 0x25 +k 0x25 +K 0x25 shift +kra 0x25 altgr +ampersand 0x25 shift altgr + +# evdev 38 (0x26), QKeyCode "l", number 0x26 +l 0x26 +L 0x26 shift +lstroke 0x26 altgr +Lstroke 0x26 shift altgr + +# evdev 39 (0x27), QKeyCode "semicolon", number 0x27 +ae 0x27 +AE 0x27 shift +dead_acute 0x27 altgr +dead_doubleacute 0x27 shift altgr + +# evdev 40 (0x28), QKeyCode "apostrophe", number 0x28 +oslash 0x28 +Oslash 0x28 shift +dead_circumflex 0x28 altgr +dead_caron 0x28 shift altgr + +# evdev 41 (0x29), QKeyCode "grave_accent", number 0x29 +onehalf 0x29 +section 0x29 shift +threequarters 0x29 altgr +paragraph 0x29 shift altgr + +# evdev 42 (0x2a), QKeyCode "shift", number 0x2a +Shift_L 0x2a + +# evdev 43 (0x2b), QKeyCode "backslash", number 0x2b +apostrophe 0x2b +asterisk 0x2b shift +dead_doubleacute 0x2b altgr +multiply 0x2b shift altgr + +# evdev 44 (0x2c), QKeyCode "z", number 0x2c +z 0x2c +Z 0x2c shift +guillemotleft 0x2c altgr +less 0x2c shift altgr + +# evdev 45 (0x2d), QKeyCode "x", number 0x2d +x 0x2d +X 0x2d shift +guillemotright 0x2d altgr +greater 0x2d shift altgr + +# evdev 46 (0x2e), QKeyCode "c", number 0x2e +c 0x2e +C 0x2e shift +copyright 0x2e altgr + +# evdev 47 (0x2f), QKeyCode "v", number 0x2f +v 0x2f +V 0x2f shift +leftdoublequotemark 0x2f altgr +leftsinglequotemark 0x2f shift altgr + +# evdev 48 (0x30), QKeyCode "b", number 0x30 +b 0x30 +B 0x30 shift +rightdoublequotemark 0x30 altgr +rightsinglequotemark 0x30 shift altgr + +# evdev 49 (0x31), QKeyCode "n", number 0x31 +n 0x31 +N 0x31 shift + +# evdev 50 (0x32), QKeyCode "m", number 0x32 +m 0x32 +M 0x32 shift +mu 0x32 altgr +masculine 0x32 shift altgr + +# evdev 51 (0x33), QKeyCode "comma", number 0x33 +comma 0x33 +semicolon 0x33 shift +dead_cedilla 0x33 altgr +dead_ogonek 0x33 shift altgr + +# evdev 52 (0x34), QKeyCode "dot", number 0x34 +period 0x34 +colon 0x34 shift +periodcentered 0x34 altgr +dead_abovedot 0x34 shift altgr + +# evdev 53 (0x35), QKeyCode "slash", number 0x35 +minus 0x35 +underscore 0x35 shift +hyphen 0x35 altgr +macron 0x35 shift altgr + +# evdev 54 (0x36), QKeyCode "shift_r", number 0x36 +Shift_R 0x36 + +# evdev 55 (0x37), QKeyCode "kp_multiply", number 0x37 +KP_Multiply 0x37 + +# evdev 56 (0x38), QKeyCode "alt", number 0x38 +Alt_L 0x38 +Meta_L 0x38 shift + +# evdev 57 (0x39), QKeyCode "spc", number 0x39 +space 0x39 +nobreakspace 0x39 altgr + +# evdev 58 (0x3a), QKeyCode "caps_lock", number 0x3a +Caps_Lock 0x3a + +# evdev 59 (0x3b), QKeyCode "f1", number 0x3b +F1 0x3b + +# evdev 60 (0x3c), QKeyCode "f2", number 0x3c +F2 0x3c + +# evdev 61 (0x3d), QKeyCode "f3", number 0x3d +F3 0x3d + +# evdev 62 (0x3e), QKeyCode "f4", number 0x3e +F4 0x3e + +# evdev 63 (0x3f), QKeyCode "f5", number 0x3f +F5 0x3f + +# evdev 64 (0x40), QKeyCode "f6", number 0x40 +F6 0x40 + +# evdev 65 (0x41), QKeyCode "f7", number 0x41 +F7 0x41 + +# evdev 66 (0x42), QKeyCode "f8", number 0x42 +F8 0x42 + +# evdev 67 (0x43), QKeyCode "f9", number 0x43 +F9 0x43 + +# evdev 68 (0x44), QKeyCode "f10", number 0x44 +F10 0x44 + +# evdev 69 (0x45), QKeyCode "num_lock", number 0x45 +Num_Lock 0x45 + +# evdev 70 (0x46), QKeyCode "scroll_lock", number 0x46 +Scroll_Lock 0x46 + +# evdev 71 (0x47), QKeyCode "kp_7", number 0x47 +KP_Home 0x47 +KP_7 0x47 numlock + +# evdev 72 (0x48), QKeyCode "kp_8", number 0x48 +KP_Up 0x48 +KP_8 0x48 numlock + +# evdev 73 (0x49), QKeyCode "kp_9", number 0x49 +KP_Prior 0x49 +KP_9 0x49 numlock + +# evdev 74 (0x4a), QKeyCode "kp_subtract", number 0x4a +KP_Subtract 0x4a + +# evdev 75 (0x4b), QKeyCode "kp_4", number 0x4b +KP_Left 0x4b +KP_4 0x4b numlock + +# evdev 76 (0x4c), QKeyCode "kp_5", number 0x4c +KP_Begin 0x4c +KP_5 0x4c numlock + +# evdev 77 (0x4d), QKeyCode "kp_6", number 0x4d +KP_Right 0x4d +KP_6 0x4d numlock + +# evdev 78 (0x4e), QKeyCode "kp_add", number 0x4e +KP_Add 0x4e + +# evdev 79 (0x4f), QKeyCode "kp_1", number 0x4f +KP_End 0x4f +KP_1 0x4f numlock + +# evdev 80 (0x50), QKeyCode "kp_2", number 0x50 +KP_Down 0x50 +KP_2 0x50 numlock + +# evdev 81 (0x51), QKeyCode "kp_3", number 0x51 +KP_Next 0x51 +KP_3 0x51 numlock + +# evdev 82 (0x52), QKeyCode "kp_0", number 0x52 +KP_Insert 0x52 +KP_0 0x52 numlock + +# evdev 83 (0x53), QKeyCode "kp_decimal", number 0x53 +KP_Delete 0x53 +KP_Decimal 0x53 numlock + +# evdev 84 (0x54): no evdev -> QKeyCode mapping (xkb keysym ISO_Level3_Shift) + +# evdev 85 (0x55): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 86 (0x56), QKeyCode "less", number 0x56 +less 0x56 +greater 0x56 shift +backslash 0x56 altgr +notsign 0x56 shift altgr + +# evdev 87 (0x57), QKeyCode "f11", number 0x57 +F11 0x57 + +# evdev 88 (0x58), QKeyCode "f12", number 0x58 +F12 0x58 + +# evdev 89 (0x59), QKeyCode "ro", number 0x73 + +# evdev 90 (0x5a): no evdev -> QKeyCode mapping (xkb keysym Katakana) + +# evdev 91 (0x5b), QKeyCode "hiragana", number 0x77 +Hiragana 0x77 + +# evdev 92 (0x5c), QKeyCode "henkan", number 0x79 +Henkan_Mode 0x79 + +# evdev 93 (0x5d), QKeyCode "katakanahiragana", number 0x70 +Hiragana_Katakana 0x70 + +# evdev 94 (0x5e), QKeyCode "muhenkan", number 0x7b +Muhenkan 0x7b + +# evdev 95 (0x5f): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 96 (0x60), QKeyCode "kp_enter", number 0x9c +KP_Enter 0x9c + +# evdev 97 (0x61), QKeyCode "ctrl_r", number 0x9d +Control_R 0x9d + +# evdev 98 (0x62), QKeyCode "kp_divide", number 0xb5 +KP_Divide 0xb5 + +# evdev 99 (0x63), QKeyCode "sysrq", number 0x54 +Print 0x54 + +# evdev 100 (0x64), QKeyCode "alt_r", number 0xb8 +ISO_Level3_Shift 0xb8 + +# evdev 101 (0x65), QKeyCode "lf", number 0x5b +Linefeed 0x5b + +# evdev 102 (0x66), QKeyCode "home", number 0xc7 +Home 0xc7 + +# evdev 103 (0x67), QKeyCode "up", number 0xc8 +Up 0xc8 + +# evdev 104 (0x68), QKeyCode "pgup", number 0xc9 +Prior 0xc9 + +# evdev 105 (0x69), QKeyCode "left", number 0xcb +Left 0xcb + +# evdev 106 (0x6a), QKeyCode "right", number 0xcd +Right 0xcd + +# evdev 107 (0x6b), QKeyCode "end", number 0xcf +End 0xcf + +# evdev 108 (0x6c), QKeyCode "down", number 0xd0 +Down 0xd0 + +# evdev 109 (0x6d), QKeyCode "pgdn", number 0xd1 +Next 0xd1 + +# evdev 110 (0x6e), QKeyCode "insert", number 0xd2 +Insert 0xd2 + +# evdev 111 (0x6f), QKeyCode "delete", number 0xd3 +Delete 0xd3 + +# evdev 112 (0x70): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 113 (0x71), QKeyCode "audiomute", number 0xa0 +XF86AudioMute 0xa0 + +# evdev 114 (0x72), QKeyCode "volumedown", number 0xae +XF86AudioLowerVolume 0xae + +# evdev 115 (0x73), QKeyCode "volumeup", number 0xb0 +XF86AudioRaiseVolume 0xb0 + +# evdev 116 (0x74), QKeyCode "power", number 0xde +XF86PowerOff 0xde + +# evdev 117 (0x75), QKeyCode "kp_equals", number 0x59 +KP_Equal 0x59 + +# evdev 118 (0x76): no evdev -> QKeyCode mapping (xkb keysym plusminus) + +# evdev 119 (0x77), QKeyCode "pause", number 0xc6 +Pause 0xc6 + +# evdev 120 (0x78): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchA) + +# evdev 121 (0x79), QKeyCode "kp_comma", number 0x7e +KP_Decimal 0x7e + +# evdev 122 (0x7a): no evdev -> QKeyCode mapping (xkb keysym Hangul) + +# evdev 123 (0x7b): no evdev -> QKeyCode mapping (xkb keysym Hangul_Hanja) + +# evdev 124 (0x7c), QKeyCode "yen", number 0x7d + +# evdev 125 (0x7d), QKeyCode "meta_l", number 0xdb +Super_L 0xdb + +# evdev 126 (0x7e), QKeyCode "meta_r", number 0xdc +Super_R 0xdc + +# evdev 127 (0x7f), QKeyCode "compose", number 0xdd +Menu 0xdd + +# evdev 128 (0x80), QKeyCode "stop", number 0xe8 +Cancel 0xe8 + +# evdev 129 (0x81), QKeyCode "again", number 0x85 +Redo 0x85 + +# evdev 130 (0x82), QKeyCode "props", number 0x86 +SunProps 0x86 + +# evdev 131 (0x83), QKeyCode "undo", number 0x87 +Undo 0x87 + +# evdev 132 (0x84), QKeyCode "front", number 0x8c +SunFront 0x8c + +# evdev 133 (0x85), QKeyCode "copy", number 0xf8 +XF86Copy 0xf8 + +# evdev 134 (0x86), QKeyCode "open", number 0x64 +XF86Open 0x64 + +# evdev 135 (0x87), QKeyCode "paste", number 0x65 +XF86Paste 0x65 + +# evdev 136 (0x88), QKeyCode "find", number 0xc1 +Find 0xc1 + +# evdev 137 (0x89), QKeyCode "cut", number 0xbc +XF86Cut 0xbc + +# evdev 138 (0x8a), QKeyCode "help", number 0xf5 +Help 0xf5 + +# evdev 139 (0x8b), QKeyCode "menu", number 0x9e +XF86MenuKB 0x9e + +# evdev 140 (0x8c), QKeyCode "calculator", number 0xa1 +XF86Calculator 0xa1 + +# evdev 141 (0x8d): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 142 (0x8e), QKeyCode "sleep", number 0xdf +XF86Sleep 0xdf + +# evdev 143 (0x8f), QKeyCode "wake", number 0xe3 +XF86WakeUp 0xe3 + +# evdev 144 (0x90): no evdev -> QKeyCode mapping (xkb keysym XF86Explorer) + +# evdev 145 (0x91): no evdev -> QKeyCode mapping (xkb keysym XF86Send) + +# evdev 146 (0x92): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 147 (0x93): no evdev -> QKeyCode mapping (xkb keysym XF86Xfer) + +# evdev 148 (0x94): no evdev -> QKeyCode mapping (xkb keysym XF86Launch1) + +# evdev 149 (0x95): no evdev -> QKeyCode mapping (xkb keysym XF86Launch2) + +# evdev 150 (0x96): no evdev -> QKeyCode mapping (xkb keysym XF86WWW) + +# evdev 151 (0x97): no evdev -> QKeyCode mapping (xkb keysym XF86DOS) + +# evdev 152 (0x98): no evdev -> QKeyCode mapping (xkb keysym XF86ScreenSaver) + +# evdev 153 (0x99): no evdev -> QKeyCode mapping (xkb keysym XF86RotateWindows) + +# evdev 154 (0x9a): no evdev -> QKeyCode mapping (xkb keysym XF86TaskPane) + +# evdev 155 (0x9b), QKeyCode "mail", number 0xec +XF86Mail 0xec + +# evdev 156 (0x9c), QKeyCode "ac_bookmarks", number 0xe6 +XF86Favorites 0xe6 + +# evdev 157 (0x9d), QKeyCode "computer", number 0xeb +XF86MyComputer 0xeb + +# evdev 158 (0x9e), QKeyCode "ac_back", number 0xea +XF86Back 0xea + +# evdev 159 (0x9f), QKeyCode "ac_forward", number 0xe9 +XF86Forward 0xe9 + +# evdev 160 (0xa0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 161 (0xa1): no evdev -> QKeyCode mapping (xkb keysym XF86Eject) + +# evdev 162 (0xa2): no evdev -> QKeyCode mapping (xkb keysym XF86Eject) + +# evdev 163 (0xa3), QKeyCode "audionext", number 0x99 +XF86AudioNext 0x99 + +# evdev 164 (0xa4), QKeyCode "audioplay", number 0xa2 +XF86AudioPlay 0xa2 +XF86AudioPause 0xa2 shift + +# evdev 165 (0xa5), QKeyCode "audioprev", number 0x90 +XF86AudioPrev 0x90 + +# evdev 166 (0xa6), QKeyCode "audiostop", number 0xa4 +XF86AudioStop 0xa4 +XF86Eject 0xa4 shift + +# evdev 167 (0xa7): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRecord) + +# evdev 168 (0xa8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRewind) + +# evdev 169 (0xa9): no evdev -> QKeyCode mapping (xkb keysym XF86Phone) + +# evdev 170 (0xaa): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 171 (0xab): no evdev -> QKeyCode mapping (xkb keysym XF86Tools) + +# evdev 172 (0xac), QKeyCode "ac_home", number 0xb2 +XF86HomePage 0xb2 + +# evdev 173 (0xad), QKeyCode "ac_refresh", number 0xe7 +XF86Reload 0xe7 + +# evdev 174 (0xae): no evdev -> QKeyCode mapping (xkb keysym XF86Close) + +# evdev 175 (0xaf): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 176 (0xb0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 177 (0xb1): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollUp) + +# evdev 178 (0xb2): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollDown) + +# evdev 179 (0xb3): no evdev -> QKeyCode mapping (xkb keysym parenleft) + +# evdev 180 (0xb4): no evdev -> QKeyCode mapping (xkb keysym parenright) + +# evdev 181 (0xb5): no evdev -> QKeyCode mapping (xkb keysym XF86New) + +# evdev 182 (0xb6): no evdev -> QKeyCode mapping (xkb keysym Redo) + +# evdev 183 (0xb7): no evdev -> QKeyCode mapping (xkb keysym XF86Tools) + +# evdev 184 (0xb8): no evdev -> QKeyCode mapping (xkb keysym XF86Launch5) + +# evdev 185 (0xb9): no evdev -> QKeyCode mapping (xkb keysym XF86Launch6) + +# evdev 186 (0xba): no evdev -> QKeyCode mapping (xkb keysym XF86Launch7) + +# evdev 187 (0xbb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch8) + +# evdev 188 (0xbc): no evdev -> QKeyCode mapping (xkb keysym XF86Launch9) + +# evdev 189 (0xbd): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 190 (0xbe): no evdev -> QKeyCode mapping (xkb keysym XF86AudioMicMute) + +# evdev 191 (0xbf): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadToggle) + +# evdev 192 (0xc0): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOn) + +# evdev 193 (0xc1): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOff) + +# evdev 194 (0xc2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 195 (0xc3): no evdev -> QKeyCode mapping (xkb keysym Mode_switch) + +# evdev 196 (0xc4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 197 (0xc5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 198 (0xc6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 199 (0xc7): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 200 (0xc8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay) + +# evdev 201 (0xc9): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPause) + +# evdev 202 (0xca): no evdev -> QKeyCode mapping (xkb keysym XF86Launch3) + +# evdev 203 (0xcb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch4) + +# evdev 204 (0xcc): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchB) + +# evdev 205 (0xcd): no evdev -> QKeyCode mapping (xkb keysym XF86Suspend) + +# evdev 206 (0xce): no evdev -> QKeyCode mapping (xkb keysym XF86Close) + +# evdev 207 (0xcf): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay) + +# evdev 208 (0xd0): no evdev -> QKeyCode mapping (xkb keysym XF86AudioForward) + +# evdev 209 (0xd1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 210 (0xd2): no evdev -> QKeyCode mapping (xkb keysym Print) + +# evdev 211 (0xd3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 212 (0xd4): no evdev -> QKeyCode mapping (xkb keysym XF86WebCam) + +# evdev 213 (0xd5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 214 (0xd6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 215 (0xd7): no evdev -> QKeyCode mapping (xkb keysym XF86Mail) + +# evdev 216 (0xd8): no evdev -> QKeyCode mapping (xkb keysym XF86Messenger) + +# evdev 217 (0xd9): no evdev -> QKeyCode mapping (xkb keysym XF86Search) + +# evdev 218 (0xda): no evdev -> QKeyCode mapping (xkb keysym XF86Go) + +# evdev 219 (0xdb): no evdev -> QKeyCode mapping (xkb keysym XF86Finance) + +# evdev 220 (0xdc): no evdev -> QKeyCode mapping (xkb keysym XF86Game) + +# evdev 221 (0xdd): no evdev -> QKeyCode mapping (xkb keysym XF86Shop) + +# evdev 222 (0xde): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 223 (0xdf): no evdev -> QKeyCode mapping (xkb keysym Cancel) + +# evdev 224 (0xe0): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessDown) + +# evdev 225 (0xe1): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessUp) + +# evdev 226 (0xe2), QKeyCode "mediaselect", number 0xed +XF86AudioMedia 0xed + +# evdev 227 (0xe3): no evdev -> QKeyCode mapping (xkb keysym XF86Display) + +# evdev 228 (0xe4): no evdev -> QKeyCode mapping (xkb keysym XF86KbdLightOnOff) + +# evdev 229 (0xe5): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessDown) + +# evdev 230 (0xe6): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessUp) + +# evdev 231 (0xe7): no evdev -> QKeyCode mapping (xkb keysym XF86Send) + +# evdev 232 (0xe8): no evdev -> QKeyCode mapping (xkb keysym XF86Reply) + +# evdev 233 (0xe9): no evdev -> QKeyCode mapping (xkb keysym XF86MailForward) + +# evdev 234 (0xea): no evdev -> QKeyCode mapping (xkb keysym XF86Save) + +# evdev 235 (0xeb): no evdev -> QKeyCode mapping (xkb keysym XF86Documents) + +# evdev 236 (0xec): no evdev -> QKeyCode mapping (xkb keysym XF86Battery) + +# evdev 237 (0xed): no evdev -> QKeyCode mapping (xkb keysym XF86Bluetooth) + +# evdev 238 (0xee): no evdev -> QKeyCode mapping (xkb keysym XF86WLAN) + +# evdev 239 (0xef): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 240 (0xf0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 241 (0xf1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 242 (0xf2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 243 (0xf3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 244 (0xf4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 245 (0xf5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 246 (0xf6): no evdev -> QKeyCode mapping (xkb keysym Invalid) + +# evdev 247 (0xf7): no evdev -> QKeyCode mapping (xkb keysym Invalid) + +# +# quirks section start +# +# Sometimes multiple keysyms map to the same keycodes. +# The keycode -> keysym lookup finds only one of the +# keysyms. So append them here. +# + +Print 0x54 +Sys_Req 0x54 +Execute 0x54 +KP_Decimal 0x53 numlock +KP_Separator 0x53 numlock +Alt_R 0xb8 +ISO_Level3_Shift 0xb8 +Mode_switch 0xb8 + +# quirks section end diff --git a/app/src/main/assets/roms/keymaps/fr b/app/src/main/assets/roms/keymaps/fr new file mode 100644 index 0000000..82ca812 --- /dev/null +++ b/app/src/main/assets/roms/keymaps/fr @@ -0,0 +1,843 @@ +# +# generated by qemu-keymap +# model : pc105 +# layout : fr +# variant : nodeadkeys +# options : - + +# name: "French (no dead keys)" + +# modifiers +# 0: Shift +# 1: Lock +# 2: Control +# 3: Mod1 +# 4: Mod2 +# 5: Mod3 +# 6: Mod4 +# 7: Mod5 +# 8: NumLock +# 9: Alt +# 10: LevelThree +# 11: LAlt +# 12: RAlt +# 13: RControl +# 14: LControl +# 15: ScrollLock +# 16: LevelFive +# 17: AltGr +# 18: Meta +# 19: Super +# 20: Hyper + +# evdev 1 (0x1), QKeyCode "esc", number 0x1 +Escape 0x01 + +# evdev 2 (0x2), QKeyCode "1", number 0x2 +ampersand 0x02 +1 0x02 shift +onesuperior 0x02 altgr +exclamdown 0x02 shift altgr + +# evdev 3 (0x3), QKeyCode "2", number 0x3 +eacute 0x03 +2 0x03 shift +asciitilde 0x03 altgr +oneeighth 0x03 shift altgr + +# evdev 4 (0x4), QKeyCode "3", number 0x4 +quotedbl 0x04 +3 0x04 shift +numbersign 0x04 altgr +sterling 0x04 shift altgr + +# evdev 5 (0x5), QKeyCode "4", number 0x5 +apostrophe 0x05 +4 0x05 shift +braceleft 0x05 altgr +dollar 0x05 shift altgr + +# evdev 6 (0x6), QKeyCode "5", number 0x6 +parenleft 0x06 +5 0x06 shift +bracketleft 0x06 altgr +threeeighths 0x06 shift altgr + +# evdev 7 (0x7), QKeyCode "6", number 0x7 +minus 0x07 +6 0x07 shift +bar 0x07 altgr +fiveeighths 0x07 shift altgr + +# evdev 8 (0x8), QKeyCode "7", number 0x8 +egrave 0x08 +7 0x08 shift +grave 0x08 altgr +seveneighths 0x08 shift altgr + +# evdev 9 (0x9), QKeyCode "8", number 0x9 +underscore 0x09 +8 0x09 shift +backslash 0x09 altgr +trademark 0x09 shift altgr + +# evdev 10 (0xa), QKeyCode "9", number 0xa +ccedilla 0x0a +9 0x0a shift +asciicircum 0x0a altgr +plusminus 0x0a shift altgr + +# evdev 11 (0xb), QKeyCode "0", number 0xb +agrave 0x0b +0 0x0b shift +at 0x0b altgr +degree 0x0b shift altgr + +# evdev 12 (0xc), QKeyCode "minus", number 0xc +parenright 0x0c +degree 0x0c shift +bracketright 0x0c altgr +questiondown 0x0c shift altgr + +# evdev 13 (0xd), QKeyCode "equal", number 0xd +equal 0x0d +plus 0x0d shift +braceright 0x0d altgr +ogonek 0x0d shift altgr + +# evdev 14 (0xe), QKeyCode "backspace", number 0xe +BackSpace 0x0e + +# evdev 15 (0xf), QKeyCode "tab", number 0xf +Tab 0x0f +ISO_Left_Tab 0x0f shift + +# evdev 16 (0x10), QKeyCode "q", number 0x10 +a 0x10 +A 0x10 shift +ae 0x10 altgr +AE 0x10 shift altgr + +# evdev 17 (0x11), QKeyCode "w", number 0x11 +z 0x11 +Z 0x11 shift +guillemotleft 0x11 altgr +less 0x11 shift altgr + +# evdev 18 (0x12), QKeyCode "e", number 0x12 +e 0x12 +E 0x12 shift +EuroSign 0x12 altgr +cent 0x12 shift altgr + +# evdev 19 (0x13), QKeyCode "r", number 0x13 +r 0x13 +R 0x13 shift +paragraph 0x13 altgr +registered 0x13 shift altgr + +# evdev 20 (0x14), QKeyCode "t", number 0x14 +t 0x14 +T 0x14 shift +tslash 0x14 altgr +Tslash 0x14 shift altgr + +# evdev 21 (0x15), QKeyCode "y", number 0x15 +y 0x15 +Y 0x15 shift +leftarrow 0x15 altgr +yen 0x15 shift altgr + +# evdev 22 (0x16), QKeyCode "u", number 0x16 +u 0x16 +U 0x16 shift +downarrow 0x16 altgr +uparrow 0x16 shift altgr + +# evdev 23 (0x17), QKeyCode "i", number 0x17 +i 0x17 +I 0x17 shift +rightarrow 0x17 altgr +idotless 0x17 shift altgr + +# evdev 24 (0x18), QKeyCode "o", number 0x18 +o 0x18 +O 0x18 shift +oslash 0x18 altgr +Oslash 0x18 shift altgr + +# evdev 25 (0x19), QKeyCode "p", number 0x19 +p 0x19 +P 0x19 shift +thorn 0x19 altgr +THORN 0x19 shift altgr + +# evdev 26 (0x1a), QKeyCode "bracket_left", number 0x1a +asciicircum 0x1a +diaeresis 0x1a shift +dead_diaeresis 0x1a altgr +dead_abovering 0x1a shift altgr + +# evdev 27 (0x1b), QKeyCode "bracket_right", number 0x1b +dollar 0x1b +sterling 0x1b shift +currency 0x1b altgr +macron 0x1b shift altgr + +# evdev 28 (0x1c), QKeyCode "ret", number 0x1c +Return 0x1c + +# evdev 29 (0x1d), QKeyCode "ctrl", number 0x1d +Control_L 0x1d + +# evdev 30 (0x1e), QKeyCode "a", number 0x1e +q 0x1e +Q 0x1e shift +at 0x1e altgr +Greek_OMEGA 0x1e shift altgr + +# evdev 31 (0x1f), QKeyCode "s", number 0x1f +s 0x1f +S 0x1f shift +ssharp 0x1f altgr +section 0x1f shift altgr + +# evdev 32 (0x20), QKeyCode "d", number 0x20 +d 0x20 +D 0x20 shift +eth 0x20 altgr +ETH 0x20 shift altgr + +# evdev 33 (0x21), QKeyCode "f", number 0x21 +f 0x21 +F 0x21 shift +dstroke 0x21 altgr +ordfeminine 0x21 shift altgr + +# evdev 34 (0x22), QKeyCode "g", number 0x22 +g 0x22 +G 0x22 shift +eng 0x22 altgr +ENG 0x22 shift altgr + +# evdev 35 (0x23), QKeyCode "h", number 0x23 +h 0x23 +H 0x23 shift +hstroke 0x23 altgr +Hstroke 0x23 shift altgr + +# evdev 36 (0x24), QKeyCode "j", number 0x24 +j 0x24 +J 0x24 shift +dead_hook 0x24 altgr +dead_horn 0x24 shift altgr + +# evdev 37 (0x25), QKeyCode "k", number 0x25 +k 0x25 +K 0x25 shift +kra 0x25 altgr +ampersand 0x25 shift altgr + +# evdev 38 (0x26), QKeyCode "l", number 0x26 +l 0x26 +L 0x26 shift +lstroke 0x26 altgr +Lstroke 0x26 shift altgr + +# evdev 39 (0x27), QKeyCode "semicolon", number 0x27 +m 0x27 +M 0x27 shift +mu 0x27 altgr +masculine 0x27 shift altgr + +# evdev 40 (0x28), QKeyCode "apostrophe", number 0x28 +ugrave 0x28 +percent 0x28 shift +asciicircum 0x28 altgr +caron 0x28 shift altgr + +# evdev 41 (0x29), QKeyCode "grave_accent", number 0x29 +twosuperior 0x29 +asciitilde 0x29 shift +notsign 0x29 altgr + +# evdev 42 (0x2a), QKeyCode "shift", number 0x2a +Shift_L 0x2a + +# evdev 43 (0x2b), QKeyCode "backslash", number 0x2b +asterisk 0x2b +mu 0x2b shift +grave 0x2b altgr +breve 0x2b shift altgr + +# evdev 44 (0x2c), QKeyCode "z", number 0x2c +w 0x2c +W 0x2c shift +lstroke 0x2c altgr +Lstroke 0x2c shift altgr + +# evdev 45 (0x2d), QKeyCode "x", number 0x2d +x 0x2d +X 0x2d shift +guillemotright 0x2d altgr +greater 0x2d shift altgr + +# evdev 46 (0x2e), QKeyCode "c", number 0x2e +c 0x2e +C 0x2e shift +cent 0x2e altgr +copyright 0x2e shift altgr + +# evdev 47 (0x2f), QKeyCode "v", number 0x2f +v 0x2f +V 0x2f shift +leftdoublequotemark 0x2f altgr +leftsinglequotemark 0x2f shift altgr + +# evdev 48 (0x30), QKeyCode "b", number 0x30 +b 0x30 +B 0x30 shift +rightdoublequotemark 0x30 altgr +rightsinglequotemark 0x30 shift altgr + +# evdev 49 (0x31), QKeyCode "n", number 0x31 +n 0x31 +N 0x31 shift + +# evdev 50 (0x32), QKeyCode "m", number 0x32 +comma 0x32 +question 0x32 shift +acute 0x32 altgr +doubleacute 0x32 shift altgr + +# evdev 51 (0x33), QKeyCode "comma", number 0x33 +semicolon 0x33 +period 0x33 shift +horizconnector 0x33 altgr +multiply 0x33 shift altgr + +# evdev 52 (0x34), QKeyCode "dot", number 0x34 +colon 0x34 +slash 0x34 shift +periodcentered 0x34 altgr +division 0x34 shift altgr + +# evdev 53 (0x35), QKeyCode "slash", number 0x35 +exclam 0x35 +section 0x35 shift +dead_belowdot 0x35 altgr +abovedot 0x35 shift altgr + +# evdev 54 (0x36), QKeyCode "shift_r", number 0x36 +Shift_R 0x36 + +# evdev 55 (0x37), QKeyCode "kp_multiply", number 0x37 +KP_Multiply 0x37 + +# evdev 56 (0x38), QKeyCode "alt", number 0x38 +Alt_L 0x38 +Meta_L 0x38 shift + +# evdev 57 (0x39), QKeyCode "spc", number 0x39 +space 0x39 + +# evdev 58 (0x3a), QKeyCode "caps_lock", number 0x3a +Caps_Lock 0x3a + +# evdev 59 (0x3b), QKeyCode "f1", number 0x3b +F1 0x3b + +# evdev 60 (0x3c), QKeyCode "f2", number 0x3c +F2 0x3c + +# evdev 61 (0x3d), QKeyCode "f3", number 0x3d +F3 0x3d + +# evdev 62 (0x3e), QKeyCode "f4", number 0x3e +F4 0x3e + +# evdev 63 (0x3f), QKeyCode "f5", number 0x3f +F5 0x3f + +# evdev 64 (0x40), QKeyCode "f6", number 0x40 +F6 0x40 + +# evdev 65 (0x41), QKeyCode "f7", number 0x41 +F7 0x41 + +# evdev 66 (0x42), QKeyCode "f8", number 0x42 +F8 0x42 + +# evdev 67 (0x43), QKeyCode "f9", number 0x43 +F9 0x43 + +# evdev 68 (0x44), QKeyCode "f10", number 0x44 +F10 0x44 + +# evdev 69 (0x45), QKeyCode "num_lock", number 0x45 +Num_Lock 0x45 + +# evdev 70 (0x46), QKeyCode "scroll_lock", number 0x46 +Scroll_Lock 0x46 + +# evdev 71 (0x47), QKeyCode "kp_7", number 0x47 +KP_Home 0x47 +KP_7 0x47 numlock + +# evdev 72 (0x48), QKeyCode "kp_8", number 0x48 +KP_Up 0x48 +KP_8 0x48 numlock + +# evdev 73 (0x49), QKeyCode "kp_9", number 0x49 +KP_Prior 0x49 +KP_9 0x49 numlock + +# evdev 74 (0x4a), QKeyCode "kp_subtract", number 0x4a +KP_Subtract 0x4a + +# evdev 75 (0x4b), QKeyCode "kp_4", number 0x4b +KP_Left 0x4b +KP_4 0x4b numlock + +# evdev 76 (0x4c), QKeyCode "kp_5", number 0x4c +KP_Begin 0x4c +KP_5 0x4c numlock + +# evdev 77 (0x4d), QKeyCode "kp_6", number 0x4d +KP_Right 0x4d +KP_6 0x4d numlock + +# evdev 78 (0x4e), QKeyCode "kp_add", number 0x4e +KP_Add 0x4e + +# evdev 79 (0x4f), QKeyCode "kp_1", number 0x4f +KP_End 0x4f +KP_1 0x4f numlock + +# evdev 80 (0x50), QKeyCode "kp_2", number 0x50 +KP_Down 0x50 +KP_2 0x50 numlock + +# evdev 81 (0x51), QKeyCode "kp_3", number 0x51 +KP_Next 0x51 +KP_3 0x51 numlock + +# evdev 82 (0x52), QKeyCode "kp_0", number 0x52 +KP_Insert 0x52 +KP_0 0x52 numlock + +# evdev 83 (0x53), QKeyCode "kp_decimal", number 0x53 +KP_Delete 0x53 +KP_Decimal 0x53 numlock + +# evdev 84 (0x54): no evdev -> QKeyCode mapping (xkb keysym ISO_Level3_Shift) + +# evdev 85 (0x55): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 86 (0x56), QKeyCode "less", number 0x56 +less 0x56 +greater 0x56 shift +bar 0x56 altgr +brokenbar 0x56 shift altgr + +# evdev 87 (0x57), QKeyCode "f11", number 0x57 +F11 0x57 + +# evdev 88 (0x58), QKeyCode "f12", number 0x58 +F12 0x58 + +# evdev 89 (0x59), QKeyCode "ro", number 0x73 + +# evdev 90 (0x5a): no evdev -> QKeyCode mapping (xkb keysym Katakana) + +# evdev 91 (0x5b), QKeyCode "hiragana", number 0x77 +Hiragana 0x77 + +# evdev 92 (0x5c), QKeyCode "henkan", number 0x79 +Henkan_Mode 0x79 + +# evdev 93 (0x5d), QKeyCode "katakanahiragana", number 0x70 +Hiragana_Katakana 0x70 + +# evdev 94 (0x5e), QKeyCode "muhenkan", number 0x7b +Muhenkan 0x7b + +# evdev 95 (0x5f): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 96 (0x60), QKeyCode "kp_enter", number 0x9c +KP_Enter 0x9c + +# evdev 97 (0x61), QKeyCode "ctrl_r", number 0x9d +Control_R 0x9d + +# evdev 98 (0x62), QKeyCode "kp_divide", number 0xb5 +KP_Divide 0xb5 + +# evdev 99 (0x63), QKeyCode "sysrq", number 0x54 +Print 0x54 + +# evdev 100 (0x64), QKeyCode "alt_r", number 0xb8 +ISO_Level3_Shift 0xb8 + +# evdev 101 (0x65), QKeyCode "lf", number 0x5b +Linefeed 0x5b + +# evdev 102 (0x66), QKeyCode "home", number 0xc7 +Home 0xc7 + +# evdev 103 (0x67), QKeyCode "up", number 0xc8 +Up 0xc8 + +# evdev 104 (0x68), QKeyCode "pgup", number 0xc9 +Prior 0xc9 + +# evdev 105 (0x69), QKeyCode "left", number 0xcb +Left 0xcb + +# evdev 106 (0x6a), QKeyCode "right", number 0xcd +Right 0xcd + +# evdev 107 (0x6b), QKeyCode "end", number 0xcf +End 0xcf + +# evdev 108 (0x6c), QKeyCode "down", number 0xd0 +Down 0xd0 + +# evdev 109 (0x6d), QKeyCode "pgdn", number 0xd1 +Next 0xd1 + +# evdev 110 (0x6e), QKeyCode "insert", number 0xd2 +Insert 0xd2 + +# evdev 111 (0x6f), QKeyCode "delete", number 0xd3 +Delete 0xd3 + +# evdev 112 (0x70): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 113 (0x71), QKeyCode "audiomute", number 0xa0 +XF86AudioMute 0xa0 + +# evdev 114 (0x72), QKeyCode "volumedown", number 0xae +XF86AudioLowerVolume 0xae + +# evdev 115 (0x73), QKeyCode "volumeup", number 0xb0 +XF86AudioRaiseVolume 0xb0 + +# evdev 116 (0x74), QKeyCode "power", number 0xde +XF86PowerOff 0xde + +# evdev 117 (0x75), QKeyCode "kp_equals", number 0x59 +KP_Equal 0x59 + +# evdev 118 (0x76): no evdev -> QKeyCode mapping (xkb keysym plusminus) + +# evdev 119 (0x77), QKeyCode "pause", number 0xc6 +Pause 0xc6 + +# evdev 120 (0x78): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchA) + +# evdev 121 (0x79), QKeyCode "kp_comma", number 0x7e +KP_Decimal 0x7e + +# evdev 122 (0x7a): no evdev -> QKeyCode mapping (xkb keysym Hangul) + +# evdev 123 (0x7b): no evdev -> QKeyCode mapping (xkb keysym Hangul_Hanja) + +# evdev 124 (0x7c), QKeyCode "yen", number 0x7d + +# evdev 125 (0x7d), QKeyCode "meta_l", number 0xdb +Super_L 0xdb + +# evdev 126 (0x7e), QKeyCode "meta_r", number 0xdc +Super_R 0xdc + +# evdev 127 (0x7f), QKeyCode "compose", number 0xdd +Menu 0xdd + +# evdev 128 (0x80), QKeyCode "stop", number 0xe8 +Cancel 0xe8 + +# evdev 129 (0x81), QKeyCode "again", number 0x85 +Redo 0x85 + +# evdev 130 (0x82), QKeyCode "props", number 0x86 +SunProps 0x86 + +# evdev 131 (0x83), QKeyCode "undo", number 0x87 +Undo 0x87 + +# evdev 132 (0x84), QKeyCode "front", number 0x8c +SunFront 0x8c + +# evdev 133 (0x85), QKeyCode "copy", number 0xf8 +XF86Copy 0xf8 + +# evdev 134 (0x86), QKeyCode "open", number 0x64 +XF86Open 0x64 + +# evdev 135 (0x87), QKeyCode "paste", number 0x65 +XF86Paste 0x65 + +# evdev 136 (0x88), QKeyCode "find", number 0xc1 +Find 0xc1 + +# evdev 137 (0x89), QKeyCode "cut", number 0xbc +XF86Cut 0xbc + +# evdev 138 (0x8a), QKeyCode "help", number 0xf5 +Help 0xf5 + +# evdev 139 (0x8b), QKeyCode "menu", number 0x9e +XF86MenuKB 0x9e + +# evdev 140 (0x8c), QKeyCode "calculator", number 0xa1 +XF86Calculator 0xa1 + +# evdev 141 (0x8d): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 142 (0x8e), QKeyCode "sleep", number 0xdf +XF86Sleep 0xdf + +# evdev 143 (0x8f), QKeyCode "wake", number 0xe3 +XF86WakeUp 0xe3 + +# evdev 144 (0x90): no evdev -> QKeyCode mapping (xkb keysym XF86Explorer) + +# evdev 145 (0x91): no evdev -> QKeyCode mapping (xkb keysym XF86Send) + +# evdev 146 (0x92): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 147 (0x93): no evdev -> QKeyCode mapping (xkb keysym XF86Xfer) + +# evdev 148 (0x94): no evdev -> QKeyCode mapping (xkb keysym XF86Launch1) + +# evdev 149 (0x95): no evdev -> QKeyCode mapping (xkb keysym XF86Launch2) + +# evdev 150 (0x96): no evdev -> QKeyCode mapping (xkb keysym XF86WWW) + +# evdev 151 (0x97): no evdev -> QKeyCode mapping (xkb keysym XF86DOS) + +# evdev 152 (0x98): no evdev -> QKeyCode mapping (xkb keysym XF86ScreenSaver) + +# evdev 153 (0x99): no evdev -> QKeyCode mapping (xkb keysym XF86RotateWindows) + +# evdev 154 (0x9a): no evdev -> QKeyCode mapping (xkb keysym XF86TaskPane) + +# evdev 155 (0x9b), QKeyCode "mail", number 0xec +XF86Mail 0xec + +# evdev 156 (0x9c), QKeyCode "ac_bookmarks", number 0xe6 +XF86Favorites 0xe6 + +# evdev 157 (0x9d), QKeyCode "computer", number 0xeb +XF86MyComputer 0xeb + +# evdev 158 (0x9e), QKeyCode "ac_back", number 0xea +XF86Back 0xea + +# evdev 159 (0x9f), QKeyCode "ac_forward", number 0xe9 +XF86Forward 0xe9 + +# evdev 160 (0xa0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 161 (0xa1): no evdev -> QKeyCode mapping (xkb keysym XF86Eject) + +# evdev 162 (0xa2): no evdev -> QKeyCode mapping (xkb keysym XF86Eject) + +# evdev 163 (0xa3), QKeyCode "audionext", number 0x99 +XF86AudioNext 0x99 + +# evdev 164 (0xa4), QKeyCode "audioplay", number 0xa2 +XF86AudioPlay 0xa2 +XF86AudioPause 0xa2 shift + +# evdev 165 (0xa5), QKeyCode "audioprev", number 0x90 +XF86AudioPrev 0x90 + +# evdev 166 (0xa6), QKeyCode "audiostop", number 0xa4 +XF86AudioStop 0xa4 +XF86Eject 0xa4 shift + +# evdev 167 (0xa7): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRecord) + +# evdev 168 (0xa8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRewind) + +# evdev 169 (0xa9): no evdev -> QKeyCode mapping (xkb keysym XF86Phone) + +# evdev 170 (0xaa): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 171 (0xab): no evdev -> QKeyCode mapping (xkb keysym XF86Tools) + +# evdev 172 (0xac), QKeyCode "ac_home", number 0xb2 +XF86HomePage 0xb2 + +# evdev 173 (0xad), QKeyCode "ac_refresh", number 0xe7 +XF86Reload 0xe7 + +# evdev 174 (0xae): no evdev -> QKeyCode mapping (xkb keysym XF86Close) + +# evdev 175 (0xaf): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 176 (0xb0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 177 (0xb1): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollUp) + +# evdev 178 (0xb2): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollDown) + +# evdev 179 (0xb3): no evdev -> QKeyCode mapping (xkb keysym parenleft) + +# evdev 180 (0xb4): no evdev -> QKeyCode mapping (xkb keysym parenright) + +# evdev 181 (0xb5): no evdev -> QKeyCode mapping (xkb keysym XF86New) + +# evdev 182 (0xb6): no evdev -> QKeyCode mapping (xkb keysym Redo) + +# evdev 183 (0xb7): no evdev -> QKeyCode mapping (xkb keysym XF86Tools) + +# evdev 184 (0xb8): no evdev -> QKeyCode mapping (xkb keysym XF86Launch5) + +# evdev 185 (0xb9): no evdev -> QKeyCode mapping (xkb keysym XF86Launch6) + +# evdev 186 (0xba): no evdev -> QKeyCode mapping (xkb keysym XF86Launch7) + +# evdev 187 (0xbb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch8) + +# evdev 188 (0xbc): no evdev -> QKeyCode mapping (xkb keysym XF86Launch9) + +# evdev 189 (0xbd): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 190 (0xbe): no evdev -> QKeyCode mapping (xkb keysym XF86AudioMicMute) + +# evdev 191 (0xbf): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadToggle) + +# evdev 192 (0xc0): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOn) + +# evdev 193 (0xc1): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOff) + +# evdev 194 (0xc2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 195 (0xc3): no evdev -> QKeyCode mapping (xkb keysym Mode_switch) + +# evdev 196 (0xc4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 197 (0xc5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 198 (0xc6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 199 (0xc7): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 200 (0xc8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay) + +# evdev 201 (0xc9): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPause) + +# evdev 202 (0xca): no evdev -> QKeyCode mapping (xkb keysym XF86Launch3) + +# evdev 203 (0xcb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch4) + +# evdev 204 (0xcc): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchB) + +# evdev 205 (0xcd): no evdev -> QKeyCode mapping (xkb keysym XF86Suspend) + +# evdev 206 (0xce): no evdev -> QKeyCode mapping (xkb keysym XF86Close) + +# evdev 207 (0xcf): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay) + +# evdev 208 (0xd0): no evdev -> QKeyCode mapping (xkb keysym XF86AudioForward) + +# evdev 209 (0xd1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 210 (0xd2): no evdev -> QKeyCode mapping (xkb keysym Print) + +# evdev 211 (0xd3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 212 (0xd4): no evdev -> QKeyCode mapping (xkb keysym XF86WebCam) + +# evdev 213 (0xd5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 214 (0xd6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 215 (0xd7): no evdev -> QKeyCode mapping (xkb keysym XF86Mail) + +# evdev 216 (0xd8): no evdev -> QKeyCode mapping (xkb keysym XF86Messenger) + +# evdev 217 (0xd9): no evdev -> QKeyCode mapping (xkb keysym XF86Search) + +# evdev 218 (0xda): no evdev -> QKeyCode mapping (xkb keysym XF86Go) + +# evdev 219 (0xdb): no evdev -> QKeyCode mapping (xkb keysym XF86Finance) + +# evdev 220 (0xdc): no evdev -> QKeyCode mapping (xkb keysym XF86Game) + +# evdev 221 (0xdd): no evdev -> QKeyCode mapping (xkb keysym XF86Shop) + +# evdev 222 (0xde): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 223 (0xdf): no evdev -> QKeyCode mapping (xkb keysym Cancel) + +# evdev 224 (0xe0): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessDown) + +# evdev 225 (0xe1): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessUp) + +# evdev 226 (0xe2), QKeyCode "mediaselect", number 0xed +XF86AudioMedia 0xed + +# evdev 227 (0xe3): no evdev -> QKeyCode mapping (xkb keysym XF86Display) + +# evdev 228 (0xe4): no evdev -> QKeyCode mapping (xkb keysym XF86KbdLightOnOff) + +# evdev 229 (0xe5): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessDown) + +# evdev 230 (0xe6): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessUp) + +# evdev 231 (0xe7): no evdev -> QKeyCode mapping (xkb keysym XF86Send) + +# evdev 232 (0xe8): no evdev -> QKeyCode mapping (xkb keysym XF86Reply) + +# evdev 233 (0xe9): no evdev -> QKeyCode mapping (xkb keysym XF86MailForward) + +# evdev 234 (0xea): no evdev -> QKeyCode mapping (xkb keysym XF86Save) + +# evdev 235 (0xeb): no evdev -> QKeyCode mapping (xkb keysym XF86Documents) + +# evdev 236 (0xec): no evdev -> QKeyCode mapping (xkb keysym XF86Battery) + +# evdev 237 (0xed): no evdev -> QKeyCode mapping (xkb keysym XF86Bluetooth) + +# evdev 238 (0xee): no evdev -> QKeyCode mapping (xkb keysym XF86WLAN) + +# evdev 239 (0xef): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 240 (0xf0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 241 (0xf1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 242 (0xf2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 243 (0xf3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 244 (0xf4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 245 (0xf5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 246 (0xf6): no evdev -> QKeyCode mapping (xkb keysym Invalid) + +# evdev 247 (0xf7): no evdev -> QKeyCode mapping (xkb keysym Invalid) + +# +# quirks section start +# +# Sometimes multiple keysyms map to the same keycodes. +# The keycode -> keysym lookup finds only one of the +# keysyms. So append them here. +# + +Print 0x54 +Sys_Req 0x54 +Execute 0x54 +KP_Decimal 0x53 numlock +KP_Separator 0x53 numlock +Alt_R 0xb8 +ISO_Level3_Shift 0xb8 +Mode_switch 0xb8 + +# quirks section end diff --git a/app/src/main/assets/roms/keymaps/fr-be b/app/src/main/assets/roms/keymaps/fr-be new file mode 100644 index 0000000..f225f17 --- /dev/null +++ b/app/src/main/assets/roms/keymaps/fr-be @@ -0,0 +1,842 @@ +# +# generated by qemu-keymap +# model : pc105 +# layout : be +# variant : - +# options : - + +# name: "Belgian" + +# modifiers +# 0: Shift +# 1: Lock +# 2: Control +# 3: Mod1 +# 4: Mod2 +# 5: Mod3 +# 6: Mod4 +# 7: Mod5 +# 8: NumLock +# 9: Alt +# 10: LevelThree +# 11: LAlt +# 12: RAlt +# 13: RControl +# 14: LControl +# 15: ScrollLock +# 16: LevelFive +# 17: AltGr +# 18: Meta +# 19: Super +# 20: Hyper + +# evdev 1 (0x1), QKeyCode "esc", number 0x1 +Escape 0x01 + +# evdev 2 (0x2), QKeyCode "1", number 0x2 +ampersand 0x02 +1 0x02 shift +bar 0x02 altgr +exclamdown 0x02 shift altgr + +# evdev 3 (0x3), QKeyCode "2", number 0x3 +eacute 0x03 +2 0x03 shift +at 0x03 altgr +oneeighth 0x03 shift altgr + +# evdev 4 (0x4), QKeyCode "3", number 0x4 +quotedbl 0x04 +3 0x04 shift +numbersign 0x04 altgr +sterling 0x04 shift altgr + +# evdev 5 (0x5), QKeyCode "4", number 0x5 +apostrophe 0x05 +4 0x05 shift +onequarter 0x05 altgr +dollar 0x05 shift altgr + +# evdev 6 (0x6), QKeyCode "5", number 0x6 +parenleft 0x06 +5 0x06 shift +onehalf 0x06 altgr +threeeighths 0x06 shift altgr + +# evdev 7 (0x7), QKeyCode "6", number 0x7 +section 0x07 +6 0x07 shift +asciicircum 0x07 altgr +fiveeighths 0x07 shift altgr + +# evdev 8 (0x8), QKeyCode "7", number 0x8 +egrave 0x08 +7 0x08 shift +braceleft 0x08 altgr +seveneighths 0x08 shift altgr + +# evdev 9 (0x9), QKeyCode "8", number 0x9 +exclam 0x09 +8 0x09 shift +bracketleft 0x09 altgr +trademark 0x09 shift altgr + +# evdev 10 (0xa), QKeyCode "9", number 0xa +ccedilla 0x0a +9 0x0a shift +braceleft 0x0a altgr +plusminus 0x0a shift altgr + +# evdev 11 (0xb), QKeyCode "0", number 0xb +agrave 0x0b +0 0x0b shift +braceright 0x0b altgr +degree 0x0b shift altgr + +# evdev 12 (0xc), QKeyCode "minus", number 0xc +parenright 0x0c +degree 0x0c shift +backslash 0x0c altgr +questiondown 0x0c shift altgr + +# evdev 13 (0xd), QKeyCode "equal", number 0xd +minus 0x0d +underscore 0x0d shift +dead_cedilla 0x0d altgr +dead_ogonek 0x0d shift altgr + +# evdev 14 (0xe), QKeyCode "backspace", number 0xe +BackSpace 0x0e + +# evdev 15 (0xf), QKeyCode "tab", number 0xf +Tab 0x0f +ISO_Left_Tab 0x0f shift + +# evdev 16 (0x10), QKeyCode "q", number 0x10 +a 0x10 +A 0x10 shift +at 0x10 altgr +Greek_OMEGA 0x10 shift altgr + +# evdev 17 (0x11), QKeyCode "w", number 0x11 +z 0x11 +Z 0x11 shift +lstroke 0x11 altgr +Lstroke 0x11 shift altgr + +# evdev 18 (0x12), QKeyCode "e", number 0x12 +e 0x12 +E 0x12 shift +EuroSign 0x12 altgr +cent 0x12 shift altgr + +# evdev 19 (0x13), QKeyCode "r", number 0x13 +r 0x13 +R 0x13 shift +paragraph 0x13 altgr +registered 0x13 shift altgr + +# evdev 20 (0x14), QKeyCode "t", number 0x14 +t 0x14 +T 0x14 shift +tslash 0x14 altgr +Tslash 0x14 shift altgr + +# evdev 21 (0x15), QKeyCode "y", number 0x15 +y 0x15 +Y 0x15 shift +leftarrow 0x15 altgr +yen 0x15 shift altgr + +# evdev 22 (0x16), QKeyCode "u", number 0x16 +u 0x16 +U 0x16 shift +downarrow 0x16 altgr +uparrow 0x16 shift altgr + +# evdev 23 (0x17), QKeyCode "i", number 0x17 +i 0x17 +I 0x17 shift +rightarrow 0x17 altgr +idotless 0x17 shift altgr + +# evdev 24 (0x18), QKeyCode "o", number 0x18 +o 0x18 +O 0x18 shift +oe 0x18 altgr +OE 0x18 shift altgr + +# evdev 25 (0x19), QKeyCode "p", number 0x19 +p 0x19 +P 0x19 shift +thorn 0x19 altgr +THORN 0x19 shift altgr + +# evdev 26 (0x1a), QKeyCode "bracket_left", number 0x1a +dead_circumflex 0x1a +dead_diaeresis 0x1a shift +bracketleft 0x1a altgr +dead_abovering 0x1a shift altgr + +# evdev 27 (0x1b), QKeyCode "bracket_right", number 0x1b +dollar 0x1b +asterisk 0x1b shift +bracketright 0x1b altgr +dead_macron 0x1b shift altgr + +# evdev 28 (0x1c), QKeyCode "ret", number 0x1c +Return 0x1c + +# evdev 29 (0x1d), QKeyCode "ctrl", number 0x1d +Control_L 0x1d + +# evdev 30 (0x1e), QKeyCode "a", number 0x1e +q 0x1e +Q 0x1e shift +ae 0x1e altgr +AE 0x1e shift altgr + +# evdev 31 (0x1f), QKeyCode "s", number 0x1f +s 0x1f +S 0x1f shift +ssharp 0x1f altgr +section 0x1f shift altgr + +# evdev 32 (0x20), QKeyCode "d", number 0x20 +d 0x20 +D 0x20 shift +eth 0x20 altgr +ETH 0x20 shift altgr + +# evdev 33 (0x21), QKeyCode "f", number 0x21 +f 0x21 +F 0x21 shift +dstroke 0x21 altgr +ordfeminine 0x21 shift altgr + +# evdev 34 (0x22), QKeyCode "g", number 0x22 +g 0x22 +G 0x22 shift +eng 0x22 altgr +ENG 0x22 shift altgr + +# evdev 35 (0x23), QKeyCode "h", number 0x23 +h 0x23 +H 0x23 shift +hstroke 0x23 altgr +Hstroke 0x23 shift altgr + +# evdev 36 (0x24), QKeyCode "j", number 0x24 +j 0x24 +J 0x24 shift +dead_hook 0x24 altgr +dead_horn 0x24 shift altgr + +# evdev 37 (0x25), QKeyCode "k", number 0x25 +k 0x25 +K 0x25 shift +kra 0x25 altgr +ampersand 0x25 shift altgr + +# evdev 38 (0x26), QKeyCode "l", number 0x26 +l 0x26 +L 0x26 shift +lstroke 0x26 altgr +Lstroke 0x26 shift altgr + +# evdev 39 (0x27), QKeyCode "semicolon", number 0x27 +m 0x27 +M 0x27 shift +dead_acute 0x27 altgr +dead_doubleacute 0x27 shift altgr + +# evdev 40 (0x28), QKeyCode "apostrophe", number 0x28 +ugrave 0x28 +percent 0x28 shift +dead_acute 0x28 altgr +dead_caron 0x28 shift altgr + +# evdev 41 (0x29), QKeyCode "grave_accent", number 0x29 +twosuperior 0x29 +threesuperior 0x29 shift +notsign 0x29 altgr + +# evdev 42 (0x2a), QKeyCode "shift", number 0x2a +Shift_L 0x2a + +# evdev 43 (0x2b), QKeyCode "backslash", number 0x2b +mu 0x2b +sterling 0x2b shift +dead_grave 0x2b altgr +dead_breve 0x2b shift altgr + +# evdev 44 (0x2c), QKeyCode "z", number 0x2c +w 0x2c +W 0x2c shift +guillemotleft 0x2c altgr +less 0x2c shift altgr + +# evdev 45 (0x2d), QKeyCode "x", number 0x2d +x 0x2d +X 0x2d shift +guillemotright 0x2d altgr +greater 0x2d shift altgr + +# evdev 46 (0x2e), QKeyCode "c", number 0x2e +c 0x2e +C 0x2e shift +cent 0x2e altgr +copyright 0x2e shift altgr + +# evdev 47 (0x2f), QKeyCode "v", number 0x2f +v 0x2f +V 0x2f shift +leftdoublequotemark 0x2f altgr +leftsinglequotemark 0x2f shift altgr + +# evdev 48 (0x30), QKeyCode "b", number 0x30 +b 0x30 +B 0x30 shift +rightdoublequotemark 0x30 altgr +rightsinglequotemark 0x30 shift altgr + +# evdev 49 (0x31), QKeyCode "n", number 0x31 +n 0x31 +N 0x31 shift + +# evdev 50 (0x32), QKeyCode "m", number 0x32 +comma 0x32 +question 0x32 shift +dead_cedilla 0x32 altgr +masculine 0x32 shift altgr + +# evdev 51 (0x33), QKeyCode "comma", number 0x33 +semicolon 0x33 +period 0x33 shift +horizconnector 0x33 altgr +multiply 0x33 shift altgr + +# evdev 52 (0x34), QKeyCode "dot", number 0x34 +colon 0x34 +slash 0x34 shift +periodcentered 0x34 altgr +division 0x34 shift altgr + +# evdev 53 (0x35), QKeyCode "slash", number 0x35 +equal 0x35 +plus 0x35 shift +dead_tilde 0x35 altgr +dead_abovedot 0x35 shift altgr + +# evdev 54 (0x36), QKeyCode "shift_r", number 0x36 +Shift_R 0x36 + +# evdev 55 (0x37), QKeyCode "kp_multiply", number 0x37 +KP_Multiply 0x37 + +# evdev 56 (0x38), QKeyCode "alt", number 0x38 +Alt_L 0x38 +Meta_L 0x38 shift + +# evdev 57 (0x39), QKeyCode "spc", number 0x39 +space 0x39 + +# evdev 58 (0x3a), QKeyCode "caps_lock", number 0x3a +Caps_Lock 0x3a + +# evdev 59 (0x3b), QKeyCode "f1", number 0x3b +F1 0x3b + +# evdev 60 (0x3c), QKeyCode "f2", number 0x3c +F2 0x3c + +# evdev 61 (0x3d), QKeyCode "f3", number 0x3d +F3 0x3d + +# evdev 62 (0x3e), QKeyCode "f4", number 0x3e +F4 0x3e + +# evdev 63 (0x3f), QKeyCode "f5", number 0x3f +F5 0x3f + +# evdev 64 (0x40), QKeyCode "f6", number 0x40 +F6 0x40 + +# evdev 65 (0x41), QKeyCode "f7", number 0x41 +F7 0x41 + +# evdev 66 (0x42), QKeyCode "f8", number 0x42 +F8 0x42 + +# evdev 67 (0x43), QKeyCode "f9", number 0x43 +F9 0x43 + +# evdev 68 (0x44), QKeyCode "f10", number 0x44 +F10 0x44 + +# evdev 69 (0x45), QKeyCode "num_lock", number 0x45 +Num_Lock 0x45 + +# evdev 70 (0x46), QKeyCode "scroll_lock", number 0x46 +Scroll_Lock 0x46 + +# evdev 71 (0x47), QKeyCode "kp_7", number 0x47 +KP_Home 0x47 +KP_7 0x47 numlock + +# evdev 72 (0x48), QKeyCode "kp_8", number 0x48 +KP_Up 0x48 +KP_8 0x48 numlock + +# evdev 73 (0x49), QKeyCode "kp_9", number 0x49 +KP_Prior 0x49 +KP_9 0x49 numlock + +# evdev 74 (0x4a), QKeyCode "kp_subtract", number 0x4a +KP_Subtract 0x4a + +# evdev 75 (0x4b), QKeyCode "kp_4", number 0x4b +KP_Left 0x4b +KP_4 0x4b numlock + +# evdev 76 (0x4c), QKeyCode "kp_5", number 0x4c +KP_Begin 0x4c +KP_5 0x4c numlock + +# evdev 77 (0x4d), QKeyCode "kp_6", number 0x4d +KP_Right 0x4d +KP_6 0x4d numlock + +# evdev 78 (0x4e), QKeyCode "kp_add", number 0x4e +KP_Add 0x4e + +# evdev 79 (0x4f), QKeyCode "kp_1", number 0x4f +KP_End 0x4f +KP_1 0x4f numlock + +# evdev 80 (0x50), QKeyCode "kp_2", number 0x50 +KP_Down 0x50 +KP_2 0x50 numlock + +# evdev 81 (0x51), QKeyCode "kp_3", number 0x51 +KP_Next 0x51 +KP_3 0x51 numlock + +# evdev 82 (0x52), QKeyCode "kp_0", number 0x52 +KP_Insert 0x52 +KP_0 0x52 numlock + +# evdev 83 (0x53), QKeyCode "kp_decimal", number 0x53 +KP_Delete 0x53 +KP_Decimal 0x53 numlock + +# evdev 84 (0x54): no evdev -> QKeyCode mapping (xkb keysym ISO_Level3_Shift) + +# evdev 85 (0x55): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 86 (0x56), QKeyCode "less", number 0x56 +less 0x56 +greater 0x56 shift +backslash 0x56 altgr + +# evdev 87 (0x57), QKeyCode "f11", number 0x57 +F11 0x57 + +# evdev 88 (0x58), QKeyCode "f12", number 0x58 +F12 0x58 + +# evdev 89 (0x59), QKeyCode "ro", number 0x73 + +# evdev 90 (0x5a): no evdev -> QKeyCode mapping (xkb keysym Katakana) + +# evdev 91 (0x5b), QKeyCode "hiragana", number 0x77 +Hiragana 0x77 + +# evdev 92 (0x5c), QKeyCode "henkan", number 0x79 +Henkan_Mode 0x79 + +# evdev 93 (0x5d), QKeyCode "katakanahiragana", number 0x70 +Hiragana_Katakana 0x70 + +# evdev 94 (0x5e), QKeyCode "muhenkan", number 0x7b +Muhenkan 0x7b + +# evdev 95 (0x5f): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 96 (0x60), QKeyCode "kp_enter", number 0x9c +KP_Enter 0x9c + +# evdev 97 (0x61), QKeyCode "ctrl_r", number 0x9d +Control_R 0x9d + +# evdev 98 (0x62), QKeyCode "kp_divide", number 0xb5 +KP_Divide 0xb5 + +# evdev 99 (0x63), QKeyCode "sysrq", number 0x54 +Print 0x54 + +# evdev 100 (0x64), QKeyCode "alt_r", number 0xb8 +ISO_Level3_Shift 0xb8 + +# evdev 101 (0x65), QKeyCode "lf", number 0x5b +Linefeed 0x5b + +# evdev 102 (0x66), QKeyCode "home", number 0xc7 +Home 0xc7 + +# evdev 103 (0x67), QKeyCode "up", number 0xc8 +Up 0xc8 + +# evdev 104 (0x68), QKeyCode "pgup", number 0xc9 +Prior 0xc9 + +# evdev 105 (0x69), QKeyCode "left", number 0xcb +Left 0xcb + +# evdev 106 (0x6a), QKeyCode "right", number 0xcd +Right 0xcd + +# evdev 107 (0x6b), QKeyCode "end", number 0xcf +End 0xcf + +# evdev 108 (0x6c), QKeyCode "down", number 0xd0 +Down 0xd0 + +# evdev 109 (0x6d), QKeyCode "pgdn", number 0xd1 +Next 0xd1 + +# evdev 110 (0x6e), QKeyCode "insert", number 0xd2 +Insert 0xd2 + +# evdev 111 (0x6f), QKeyCode "delete", number 0xd3 +Delete 0xd3 + +# evdev 112 (0x70): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 113 (0x71), QKeyCode "audiomute", number 0xa0 +XF86AudioMute 0xa0 + +# evdev 114 (0x72), QKeyCode "volumedown", number 0xae +XF86AudioLowerVolume 0xae + +# evdev 115 (0x73), QKeyCode "volumeup", number 0xb0 +XF86AudioRaiseVolume 0xb0 + +# evdev 116 (0x74), QKeyCode "power", number 0xde +XF86PowerOff 0xde + +# evdev 117 (0x75), QKeyCode "kp_equals", number 0x59 +KP_Equal 0x59 + +# evdev 118 (0x76): no evdev -> QKeyCode mapping (xkb keysym plusminus) + +# evdev 119 (0x77), QKeyCode "pause", number 0xc6 +Pause 0xc6 + +# evdev 120 (0x78): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchA) + +# evdev 121 (0x79), QKeyCode "kp_comma", number 0x7e +KP_Decimal 0x7e + +# evdev 122 (0x7a): no evdev -> QKeyCode mapping (xkb keysym Hangul) + +# evdev 123 (0x7b): no evdev -> QKeyCode mapping (xkb keysym Hangul_Hanja) + +# evdev 124 (0x7c), QKeyCode "yen", number 0x7d + +# evdev 125 (0x7d), QKeyCode "meta_l", number 0xdb +Super_L 0xdb + +# evdev 126 (0x7e), QKeyCode "meta_r", number 0xdc +Super_R 0xdc + +# evdev 127 (0x7f), QKeyCode "compose", number 0xdd +Menu 0xdd + +# evdev 128 (0x80), QKeyCode "stop", number 0xe8 +Cancel 0xe8 + +# evdev 129 (0x81), QKeyCode "again", number 0x85 +Redo 0x85 + +# evdev 130 (0x82), QKeyCode "props", number 0x86 +SunProps 0x86 + +# evdev 131 (0x83), QKeyCode "undo", number 0x87 +Undo 0x87 + +# evdev 132 (0x84), QKeyCode "front", number 0x8c +SunFront 0x8c + +# evdev 133 (0x85), QKeyCode "copy", number 0xf8 +XF86Copy 0xf8 + +# evdev 134 (0x86), QKeyCode "open", number 0x64 +XF86Open 0x64 + +# evdev 135 (0x87), QKeyCode "paste", number 0x65 +XF86Paste 0x65 + +# evdev 136 (0x88), QKeyCode "find", number 0xc1 +Find 0xc1 + +# evdev 137 (0x89), QKeyCode "cut", number 0xbc +XF86Cut 0xbc + +# evdev 138 (0x8a), QKeyCode "help", number 0xf5 +Help 0xf5 + +# evdev 139 (0x8b), QKeyCode "menu", number 0x9e +XF86MenuKB 0x9e + +# evdev 140 (0x8c), QKeyCode "calculator", number 0xa1 +XF86Calculator 0xa1 + +# evdev 141 (0x8d): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 142 (0x8e), QKeyCode "sleep", number 0xdf +XF86Sleep 0xdf + +# evdev 143 (0x8f), QKeyCode "wake", number 0xe3 +XF86WakeUp 0xe3 + +# evdev 144 (0x90): no evdev -> QKeyCode mapping (xkb keysym XF86Explorer) + +# evdev 145 (0x91): no evdev -> QKeyCode mapping (xkb keysym XF86Send) + +# evdev 146 (0x92): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 147 (0x93): no evdev -> QKeyCode mapping (xkb keysym XF86Xfer) + +# evdev 148 (0x94): no evdev -> QKeyCode mapping (xkb keysym XF86Launch1) + +# evdev 149 (0x95): no evdev -> QKeyCode mapping (xkb keysym XF86Launch2) + +# evdev 150 (0x96): no evdev -> QKeyCode mapping (xkb keysym XF86WWW) + +# evdev 151 (0x97): no evdev -> QKeyCode mapping (xkb keysym XF86DOS) + +# evdev 152 (0x98): no evdev -> QKeyCode mapping (xkb keysym XF86ScreenSaver) + +# evdev 153 (0x99): no evdev -> QKeyCode mapping (xkb keysym XF86RotateWindows) + +# evdev 154 (0x9a): no evdev -> QKeyCode mapping (xkb keysym XF86TaskPane) + +# evdev 155 (0x9b), QKeyCode "mail", number 0xec +XF86Mail 0xec + +# evdev 156 (0x9c), QKeyCode "ac_bookmarks", number 0xe6 +XF86Favorites 0xe6 + +# evdev 157 (0x9d), QKeyCode "computer", number 0xeb +XF86MyComputer 0xeb + +# evdev 158 (0x9e), QKeyCode "ac_back", number 0xea +XF86Back 0xea + +# evdev 159 (0x9f), QKeyCode "ac_forward", number 0xe9 +XF86Forward 0xe9 + +# evdev 160 (0xa0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 161 (0xa1): no evdev -> QKeyCode mapping (xkb keysym XF86Eject) + +# evdev 162 (0xa2): no evdev -> QKeyCode mapping (xkb keysym XF86Eject) + +# evdev 163 (0xa3), QKeyCode "audionext", number 0x99 +XF86AudioNext 0x99 + +# evdev 164 (0xa4), QKeyCode "audioplay", number 0xa2 +XF86AudioPlay 0xa2 +XF86AudioPause 0xa2 shift + +# evdev 165 (0xa5), QKeyCode "audioprev", number 0x90 +XF86AudioPrev 0x90 + +# evdev 166 (0xa6), QKeyCode "audiostop", number 0xa4 +XF86AudioStop 0xa4 +XF86Eject 0xa4 shift + +# evdev 167 (0xa7): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRecord) + +# evdev 168 (0xa8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRewind) + +# evdev 169 (0xa9): no evdev -> QKeyCode mapping (xkb keysym XF86Phone) + +# evdev 170 (0xaa): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 171 (0xab): no evdev -> QKeyCode mapping (xkb keysym XF86Tools) + +# evdev 172 (0xac), QKeyCode "ac_home", number 0xb2 +XF86HomePage 0xb2 + +# evdev 173 (0xad), QKeyCode "ac_refresh", number 0xe7 +XF86Reload 0xe7 + +# evdev 174 (0xae): no evdev -> QKeyCode mapping (xkb keysym XF86Close) + +# evdev 175 (0xaf): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 176 (0xb0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 177 (0xb1): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollUp) + +# evdev 178 (0xb2): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollDown) + +# evdev 179 (0xb3): no evdev -> QKeyCode mapping (xkb keysym parenleft) + +# evdev 180 (0xb4): no evdev -> QKeyCode mapping (xkb keysym parenright) + +# evdev 181 (0xb5): no evdev -> QKeyCode mapping (xkb keysym XF86New) + +# evdev 182 (0xb6): no evdev -> QKeyCode mapping (xkb keysym Redo) + +# evdev 183 (0xb7): no evdev -> QKeyCode mapping (xkb keysym XF86Tools) + +# evdev 184 (0xb8): no evdev -> QKeyCode mapping (xkb keysym XF86Launch5) + +# evdev 185 (0xb9): no evdev -> QKeyCode mapping (xkb keysym XF86Launch6) + +# evdev 186 (0xba): no evdev -> QKeyCode mapping (xkb keysym XF86Launch7) + +# evdev 187 (0xbb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch8) + +# evdev 188 (0xbc): no evdev -> QKeyCode mapping (xkb keysym XF86Launch9) + +# evdev 189 (0xbd): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 190 (0xbe): no evdev -> QKeyCode mapping (xkb keysym XF86AudioMicMute) + +# evdev 191 (0xbf): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadToggle) + +# evdev 192 (0xc0): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOn) + +# evdev 193 (0xc1): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOff) + +# evdev 194 (0xc2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 195 (0xc3): no evdev -> QKeyCode mapping (xkb keysym Mode_switch) + +# evdev 196 (0xc4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 197 (0xc5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 198 (0xc6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 199 (0xc7): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 200 (0xc8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay) + +# evdev 201 (0xc9): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPause) + +# evdev 202 (0xca): no evdev -> QKeyCode mapping (xkb keysym XF86Launch3) + +# evdev 203 (0xcb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch4) + +# evdev 204 (0xcc): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchB) + +# evdev 205 (0xcd): no evdev -> QKeyCode mapping (xkb keysym XF86Suspend) + +# evdev 206 (0xce): no evdev -> QKeyCode mapping (xkb keysym XF86Close) + +# evdev 207 (0xcf): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay) + +# evdev 208 (0xd0): no evdev -> QKeyCode mapping (xkb keysym XF86AudioForward) + +# evdev 209 (0xd1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 210 (0xd2): no evdev -> QKeyCode mapping (xkb keysym Print) + +# evdev 211 (0xd3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 212 (0xd4): no evdev -> QKeyCode mapping (xkb keysym XF86WebCam) + +# evdev 213 (0xd5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 214 (0xd6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 215 (0xd7): no evdev -> QKeyCode mapping (xkb keysym XF86Mail) + +# evdev 216 (0xd8): no evdev -> QKeyCode mapping (xkb keysym XF86Messenger) + +# evdev 217 (0xd9): no evdev -> QKeyCode mapping (xkb keysym XF86Search) + +# evdev 218 (0xda): no evdev -> QKeyCode mapping (xkb keysym XF86Go) + +# evdev 219 (0xdb): no evdev -> QKeyCode mapping (xkb keysym XF86Finance) + +# evdev 220 (0xdc): no evdev -> QKeyCode mapping (xkb keysym XF86Game) + +# evdev 221 (0xdd): no evdev -> QKeyCode mapping (xkb keysym XF86Shop) + +# evdev 222 (0xde): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 223 (0xdf): no evdev -> QKeyCode mapping (xkb keysym Cancel) + +# evdev 224 (0xe0): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessDown) + +# evdev 225 (0xe1): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessUp) + +# evdev 226 (0xe2), QKeyCode "mediaselect", number 0xed +XF86AudioMedia 0xed + +# evdev 227 (0xe3): no evdev -> QKeyCode mapping (xkb keysym XF86Display) + +# evdev 228 (0xe4): no evdev -> QKeyCode mapping (xkb keysym XF86KbdLightOnOff) + +# evdev 229 (0xe5): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessDown) + +# evdev 230 (0xe6): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessUp) + +# evdev 231 (0xe7): no evdev -> QKeyCode mapping (xkb keysym XF86Send) + +# evdev 232 (0xe8): no evdev -> QKeyCode mapping (xkb keysym XF86Reply) + +# evdev 233 (0xe9): no evdev -> QKeyCode mapping (xkb keysym XF86MailForward) + +# evdev 234 (0xea): no evdev -> QKeyCode mapping (xkb keysym XF86Save) + +# evdev 235 (0xeb): no evdev -> QKeyCode mapping (xkb keysym XF86Documents) + +# evdev 236 (0xec): no evdev -> QKeyCode mapping (xkb keysym XF86Battery) + +# evdev 237 (0xed): no evdev -> QKeyCode mapping (xkb keysym XF86Bluetooth) + +# evdev 238 (0xee): no evdev -> QKeyCode mapping (xkb keysym XF86WLAN) + +# evdev 239 (0xef): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 240 (0xf0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 241 (0xf1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 242 (0xf2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 243 (0xf3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 244 (0xf4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 245 (0xf5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 246 (0xf6): no evdev -> QKeyCode mapping (xkb keysym Invalid) + +# evdev 247 (0xf7): no evdev -> QKeyCode mapping (xkb keysym Invalid) + +# +# quirks section start +# +# Sometimes multiple keysyms map to the same keycodes. +# The keycode -> keysym lookup finds only one of the +# keysyms. So append them here. +# + +Print 0x54 +Sys_Req 0x54 +Execute 0x54 +KP_Decimal 0x53 numlock +KP_Separator 0x53 numlock +Alt_R 0xb8 +ISO_Level3_Shift 0xb8 +Mode_switch 0xb8 + +# quirks section end diff --git a/app/src/main/assets/roms/keymaps/fr-ca b/app/src/main/assets/roms/keymaps/fr-ca new file mode 100644 index 0000000..f264d0a --- /dev/null +++ b/app/src/main/assets/roms/keymaps/fr-ca @@ -0,0 +1,774 @@ +# +# generated by qemu-keymap +# model : pc105 +# layout : ca +# variant : fr +# options : - + +# name: "French (Canada)" + +# modifiers +# 0: Shift +# 1: Lock +# 2: Control +# 3: Mod1 +# 4: Mod2 +# 5: Mod3 +# 6: Mod4 +# 7: Mod5 +# 8: NumLock +# 9: Alt +# 10: LevelThree +# 11: LAlt +# 12: RAlt +# 13: RControl +# 14: LControl +# 15: ScrollLock +# 16: LevelFive +# 17: AltGr +# 18: Meta +# 19: Super +# 20: Hyper + +# evdev 1 (0x1), QKeyCode "esc", number 0x1 +Escape 0x01 + +# evdev 2 (0x2), QKeyCode "1", number 0x2 +1 0x02 +exclam 0x02 shift +plusminus 0x02 altgr + +# evdev 3 (0x3), QKeyCode "2", number 0x3 +2 0x03 +quotedbl 0x03 shift +at 0x03 altgr + +# evdev 4 (0x4), QKeyCode "3", number 0x4 +3 0x04 +slash 0x04 shift +sterling 0x04 altgr + +# evdev 5 (0x5), QKeyCode "4", number 0x5 +4 0x05 +dollar 0x05 shift +cent 0x05 altgr + +# evdev 6 (0x6), QKeyCode "5", number 0x6 +5 0x06 +percent 0x06 shift +currency 0x06 altgr + +# evdev 7 (0x7), QKeyCode "6", number 0x7 +6 0x07 +question 0x07 shift +notsign 0x07 altgr + +# evdev 8 (0x8), QKeyCode "7", number 0x8 +7 0x08 +ampersand 0x08 shift +brokenbar 0x08 altgr + +# evdev 9 (0x9), QKeyCode "8", number 0x9 +8 0x09 +asterisk 0x09 shift +twosuperior 0x09 altgr + +# evdev 10 (0xa), QKeyCode "9", number 0xa +9 0x0a +parenleft 0x0a shift +threesuperior 0x0a altgr + +# evdev 11 (0xb), QKeyCode "0", number 0xb +0 0x0b +parenright 0x0b shift +onequarter 0x0b altgr + +# evdev 12 (0xc), QKeyCode "minus", number 0xc +minus 0x0c +underscore 0x0c shift +onehalf 0x0c altgr + +# evdev 13 (0xd), QKeyCode "equal", number 0xd +equal 0x0d +plus 0x0d shift +threequarters 0x0d altgr + +# evdev 14 (0xe), QKeyCode "backspace", number 0xe +BackSpace 0x0e + +# evdev 15 (0xf), QKeyCode "tab", number 0xf +Tab 0x0f +ISO_Left_Tab 0x0f shift + +# evdev 16 (0x10), QKeyCode "q", number 0x10 +q 0x10 +Q 0x10 shift + +# evdev 17 (0x11), QKeyCode "w", number 0x11 +w 0x11 +W 0x11 shift + +# evdev 18 (0x12), QKeyCode "e", number 0x12 +e 0x12 +E 0x12 shift + +# evdev 19 (0x13), QKeyCode "r", number 0x13 +r 0x13 +R 0x13 shift + +# evdev 20 (0x14), QKeyCode "t", number 0x14 +t 0x14 +T 0x14 shift + +# evdev 21 (0x15), QKeyCode "y", number 0x15 +y 0x15 +Y 0x15 shift + +# evdev 22 (0x16), QKeyCode "u", number 0x16 +u 0x16 +U 0x16 shift + +# evdev 23 (0x17), QKeyCode "i", number 0x17 +i 0x17 +I 0x17 shift + +# evdev 24 (0x18), QKeyCode "o", number 0x18 +o 0x18 +O 0x18 shift +section 0x18 altgr + +# evdev 25 (0x19), QKeyCode "p", number 0x19 +p 0x19 +P 0x19 shift +paragraph 0x19 altgr + +# evdev 26 (0x1a), QKeyCode "bracket_left", number 0x1a +dead_circumflex 0x1a +bracketleft 0x1a altgr + +# evdev 27 (0x1b), QKeyCode "bracket_right", number 0x1b +dead_cedilla 0x1b +dead_diaeresis 0x1b shift +bracketright 0x1b altgr + +# evdev 28 (0x1c), QKeyCode "ret", number 0x1c +Return 0x1c + +# evdev 29 (0x1d), QKeyCode "ctrl", number 0x1d +Control_L 0x1d + +# evdev 30 (0x1e), QKeyCode "a", number 0x1e +a 0x1e +A 0x1e shift + +# evdev 31 (0x1f), QKeyCode "s", number 0x1f +s 0x1f +S 0x1f shift + +# evdev 32 (0x20), QKeyCode "d", number 0x20 +d 0x20 +D 0x20 shift + +# evdev 33 (0x21), QKeyCode "f", number 0x21 +f 0x21 +F 0x21 shift + +# evdev 34 (0x22), QKeyCode "g", number 0x22 +g 0x22 +G 0x22 shift + +# evdev 35 (0x23), QKeyCode "h", number 0x23 +h 0x23 +H 0x23 shift + +# evdev 36 (0x24), QKeyCode "j", number 0x24 +j 0x24 +J 0x24 shift + +# evdev 37 (0x25), QKeyCode "k", number 0x25 +k 0x25 +K 0x25 shift + +# evdev 38 (0x26), QKeyCode "l", number 0x26 +l 0x26 +L 0x26 shift + +# evdev 39 (0x27), QKeyCode "semicolon", number 0x27 +semicolon 0x27 +colon 0x27 shift +asciitilde 0x27 altgr + +# evdev 40 (0x28), QKeyCode "apostrophe", number 0x28 +dead_grave 0x28 +braceleft 0x28 altgr + +# evdev 41 (0x29), QKeyCode "grave_accent", number 0x29 +numbersign 0x29 +bar 0x29 shift +backslash 0x29 altgr + +# evdev 42 (0x2a), QKeyCode "shift", number 0x2a +Shift_L 0x2a + +# evdev 43 (0x2b), QKeyCode "backslash", number 0x2b +less 0x2b +greater 0x2b shift +braceright 0x2b altgr + +# evdev 44 (0x2c), QKeyCode "z", number 0x2c +z 0x2c +Z 0x2c shift + +# evdev 45 (0x2d), QKeyCode "x", number 0x2d +x 0x2d +X 0x2d shift + +# evdev 46 (0x2e), QKeyCode "c", number 0x2e +c 0x2e +C 0x2e shift + +# evdev 47 (0x2f), QKeyCode "v", number 0x2f +v 0x2f +V 0x2f shift + +# evdev 48 (0x30), QKeyCode "b", number 0x30 +b 0x30 +B 0x30 shift + +# evdev 49 (0x31), QKeyCode "n", number 0x31 +n 0x31 +N 0x31 shift + +# evdev 50 (0x32), QKeyCode "m", number 0x32 +m 0x32 +M 0x32 shift +mu 0x32 altgr + +# evdev 51 (0x33), QKeyCode "comma", number 0x33 +comma 0x33 +apostrophe 0x33 shift +macron 0x33 altgr + +# evdev 52 (0x34), QKeyCode "dot", number 0x34 +period 0x34 +hyphen 0x34 altgr + +# evdev 53 (0x35), QKeyCode "slash", number 0x35 +eacute 0x35 +Eacute 0x35 shift +dead_acute 0x35 altgr + +# evdev 54 (0x36), QKeyCode "shift_r", number 0x36 +Shift_R 0x36 + +# evdev 55 (0x37), QKeyCode "kp_multiply", number 0x37 +KP_Multiply 0x37 + +# evdev 56 (0x38), QKeyCode "alt", number 0x38 +Alt_L 0x38 +Meta_L 0x38 shift + +# evdev 57 (0x39), QKeyCode "spc", number 0x39 +space 0x39 +nobreakspace 0x39 altgr + +# evdev 58 (0x3a), QKeyCode "caps_lock", number 0x3a +Caps_Lock 0x3a + +# evdev 59 (0x3b), QKeyCode "f1", number 0x3b +F1 0x3b + +# evdev 60 (0x3c), QKeyCode "f2", number 0x3c +F2 0x3c + +# evdev 61 (0x3d), QKeyCode "f3", number 0x3d +F3 0x3d + +# evdev 62 (0x3e), QKeyCode "f4", number 0x3e +F4 0x3e + +# evdev 63 (0x3f), QKeyCode "f5", number 0x3f +F5 0x3f + +# evdev 64 (0x40), QKeyCode "f6", number 0x40 +F6 0x40 + +# evdev 65 (0x41), QKeyCode "f7", number 0x41 +F7 0x41 + +# evdev 66 (0x42), QKeyCode "f8", number 0x42 +F8 0x42 + +# evdev 67 (0x43), QKeyCode "f9", number 0x43 +F9 0x43 + +# evdev 68 (0x44), QKeyCode "f10", number 0x44 +F10 0x44 + +# evdev 69 (0x45), QKeyCode "num_lock", number 0x45 +Num_Lock 0x45 + +# evdev 70 (0x46), QKeyCode "scroll_lock", number 0x46 +Scroll_Lock 0x46 + +# evdev 71 (0x47), QKeyCode "kp_7", number 0x47 +KP_Home 0x47 +KP_7 0x47 numlock + +# evdev 72 (0x48), QKeyCode "kp_8", number 0x48 +KP_Up 0x48 +KP_8 0x48 numlock + +# evdev 73 (0x49), QKeyCode "kp_9", number 0x49 +KP_Prior 0x49 +KP_9 0x49 numlock + +# evdev 74 (0x4a), QKeyCode "kp_subtract", number 0x4a +KP_Subtract 0x4a + +# evdev 75 (0x4b), QKeyCode "kp_4", number 0x4b +KP_Left 0x4b +KP_4 0x4b numlock + +# evdev 76 (0x4c), QKeyCode "kp_5", number 0x4c +KP_Begin 0x4c +KP_5 0x4c numlock + +# evdev 77 (0x4d), QKeyCode "kp_6", number 0x4d +KP_Right 0x4d +KP_6 0x4d numlock + +# evdev 78 (0x4e), QKeyCode "kp_add", number 0x4e +KP_Add 0x4e + +# evdev 79 (0x4f), QKeyCode "kp_1", number 0x4f +KP_End 0x4f +KP_1 0x4f numlock + +# evdev 80 (0x50), QKeyCode "kp_2", number 0x50 +KP_Down 0x50 +KP_2 0x50 numlock + +# evdev 81 (0x51), QKeyCode "kp_3", number 0x51 +KP_Next 0x51 +KP_3 0x51 numlock + +# evdev 82 (0x52), QKeyCode "kp_0", number 0x52 +KP_Insert 0x52 +KP_0 0x52 numlock + +# evdev 83 (0x53), QKeyCode "kp_decimal", number 0x53 +KP_Delete 0x53 +KP_Decimal 0x53 numlock + +# evdev 84 (0x54): no evdev -> QKeyCode mapping (xkb keysym ISO_Level3_Shift) + +# evdev 85 (0x55): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 86 (0x56), QKeyCode "less", number 0x56 +guillemotleft 0x56 +guillemotright 0x56 shift +degree 0x56 altgr +brokenbar 0x56 shift altgr + +# evdev 87 (0x57), QKeyCode "f11", number 0x57 +F11 0x57 + +# evdev 88 (0x58), QKeyCode "f12", number 0x58 +F12 0x58 + +# evdev 89 (0x59), QKeyCode "ro", number 0x73 + +# evdev 90 (0x5a): no evdev -> QKeyCode mapping (xkb keysym Katakana) + +# evdev 91 (0x5b), QKeyCode "hiragana", number 0x77 +Hiragana 0x77 + +# evdev 92 (0x5c), QKeyCode "henkan", number 0x79 +Henkan_Mode 0x79 + +# evdev 93 (0x5d), QKeyCode "katakanahiragana", number 0x70 +Hiragana_Katakana 0x70 + +# evdev 94 (0x5e), QKeyCode "muhenkan", number 0x7b +Muhenkan 0x7b + +# evdev 95 (0x5f): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 96 (0x60), QKeyCode "kp_enter", number 0x9c +KP_Enter 0x9c + +# evdev 97 (0x61), QKeyCode "ctrl_r", number 0x9d +Control_R 0x9d + +# evdev 98 (0x62), QKeyCode "kp_divide", number 0xb5 +KP_Divide 0xb5 + +# evdev 99 (0x63), QKeyCode "sysrq", number 0x54 +Print 0x54 + +# evdev 100 (0x64), QKeyCode "alt_r", number 0xb8 +ISO_Level3_Shift 0xb8 + +# evdev 101 (0x65), QKeyCode "lf", number 0x5b +Linefeed 0x5b + +# evdev 102 (0x66), QKeyCode "home", number 0xc7 +Home 0xc7 + +# evdev 103 (0x67), QKeyCode "up", number 0xc8 +Up 0xc8 + +# evdev 104 (0x68), QKeyCode "pgup", number 0xc9 +Prior 0xc9 + +# evdev 105 (0x69), QKeyCode "left", number 0xcb +Left 0xcb + +# evdev 106 (0x6a), QKeyCode "right", number 0xcd +Right 0xcd + +# evdev 107 (0x6b), QKeyCode "end", number 0xcf +End 0xcf + +# evdev 108 (0x6c), QKeyCode "down", number 0xd0 +Down 0xd0 + +# evdev 109 (0x6d), QKeyCode "pgdn", number 0xd1 +Next 0xd1 + +# evdev 110 (0x6e), QKeyCode "insert", number 0xd2 +Insert 0xd2 + +# evdev 111 (0x6f), QKeyCode "delete", number 0xd3 +Delete 0xd3 + +# evdev 112 (0x70): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 113 (0x71), QKeyCode "audiomute", number 0xa0 +XF86AudioMute 0xa0 + +# evdev 114 (0x72), QKeyCode "volumedown", number 0xae +XF86AudioLowerVolume 0xae + +# evdev 115 (0x73), QKeyCode "volumeup", number 0xb0 +XF86AudioRaiseVolume 0xb0 + +# evdev 116 (0x74), QKeyCode "power", number 0xde +XF86PowerOff 0xde + +# evdev 117 (0x75), QKeyCode "kp_equals", number 0x59 +KP_Equal 0x59 + +# evdev 118 (0x76): no evdev -> QKeyCode mapping (xkb keysym plusminus) + +# evdev 119 (0x77), QKeyCode "pause", number 0xc6 +Pause 0xc6 + +# evdev 120 (0x78): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchA) + +# evdev 121 (0x79), QKeyCode "kp_comma", number 0x7e +KP_Decimal 0x7e + +# evdev 122 (0x7a): no evdev -> QKeyCode mapping (xkb keysym Hangul) + +# evdev 123 (0x7b): no evdev -> QKeyCode mapping (xkb keysym Hangul_Hanja) + +# evdev 124 (0x7c), QKeyCode "yen", number 0x7d + +# evdev 125 (0x7d), QKeyCode "meta_l", number 0xdb +Super_L 0xdb + +# evdev 126 (0x7e), QKeyCode "meta_r", number 0xdc +Super_R 0xdc + +# evdev 127 (0x7f), QKeyCode "compose", number 0xdd +Menu 0xdd + +# evdev 128 (0x80), QKeyCode "stop", number 0xe8 +Cancel 0xe8 + +# evdev 129 (0x81), QKeyCode "again", number 0x85 +Redo 0x85 + +# evdev 130 (0x82), QKeyCode "props", number 0x86 +SunProps 0x86 + +# evdev 131 (0x83), QKeyCode "undo", number 0x87 +Undo 0x87 + +# evdev 132 (0x84), QKeyCode "front", number 0x8c +SunFront 0x8c + +# evdev 133 (0x85), QKeyCode "copy", number 0xf8 +XF86Copy 0xf8 + +# evdev 134 (0x86), QKeyCode "open", number 0x64 +XF86Open 0x64 + +# evdev 135 (0x87), QKeyCode "paste", number 0x65 +XF86Paste 0x65 + +# evdev 136 (0x88), QKeyCode "find", number 0xc1 +Find 0xc1 + +# evdev 137 (0x89), QKeyCode "cut", number 0xbc +XF86Cut 0xbc + +# evdev 138 (0x8a), QKeyCode "help", number 0xf5 +Help 0xf5 + +# evdev 139 (0x8b), QKeyCode "menu", number 0x9e +XF86MenuKB 0x9e + +# evdev 140 (0x8c), QKeyCode "calculator", number 0xa1 +XF86Calculator 0xa1 + +# evdev 141 (0x8d): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 142 (0x8e), QKeyCode "sleep", number 0xdf +XF86Sleep 0xdf + +# evdev 143 (0x8f), QKeyCode "wake", number 0xe3 +XF86WakeUp 0xe3 + +# evdev 144 (0x90): no evdev -> QKeyCode mapping (xkb keysym XF86Explorer) + +# evdev 145 (0x91): no evdev -> QKeyCode mapping (xkb keysym XF86Send) + +# evdev 146 (0x92): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 147 (0x93): no evdev -> QKeyCode mapping (xkb keysym XF86Xfer) + +# evdev 148 (0x94): no evdev -> QKeyCode mapping (xkb keysym XF86Launch1) + +# evdev 149 (0x95): no evdev -> QKeyCode mapping (xkb keysym XF86Launch2) + +# evdev 150 (0x96): no evdev -> QKeyCode mapping (xkb keysym XF86WWW) + +# evdev 151 (0x97): no evdev -> QKeyCode mapping (xkb keysym XF86DOS) + +# evdev 152 (0x98): no evdev -> QKeyCode mapping (xkb keysym XF86ScreenSaver) + +# evdev 153 (0x99): no evdev -> QKeyCode mapping (xkb keysym XF86RotateWindows) + +# evdev 154 (0x9a): no evdev -> QKeyCode mapping (xkb keysym XF86TaskPane) + +# evdev 155 (0x9b), QKeyCode "mail", number 0xec +XF86Mail 0xec + +# evdev 156 (0x9c), QKeyCode "ac_bookmarks", number 0xe6 +XF86Favorites 0xe6 + +# evdev 157 (0x9d), QKeyCode "computer", number 0xeb +XF86MyComputer 0xeb + +# evdev 158 (0x9e), QKeyCode "ac_back", number 0xea +XF86Back 0xea + +# evdev 159 (0x9f), QKeyCode "ac_forward", number 0xe9 +XF86Forward 0xe9 + +# evdev 160 (0xa0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 161 (0xa1): no evdev -> QKeyCode mapping (xkb keysym XF86Eject) + +# evdev 162 (0xa2): no evdev -> QKeyCode mapping (xkb keysym XF86Eject) + +# evdev 163 (0xa3), QKeyCode "audionext", number 0x99 +XF86AudioNext 0x99 + +# evdev 164 (0xa4), QKeyCode "audioplay", number 0xa2 +XF86AudioPlay 0xa2 +XF86AudioPause 0xa2 shift + +# evdev 165 (0xa5), QKeyCode "audioprev", number 0x90 +XF86AudioPrev 0x90 + +# evdev 166 (0xa6), QKeyCode "audiostop", number 0xa4 +XF86AudioStop 0xa4 +XF86Eject 0xa4 shift + +# evdev 167 (0xa7): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRecord) + +# evdev 168 (0xa8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRewind) + +# evdev 169 (0xa9): no evdev -> QKeyCode mapping (xkb keysym XF86Phone) + +# evdev 170 (0xaa): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 171 (0xab): no evdev -> QKeyCode mapping (xkb keysym XF86Tools) + +# evdev 172 (0xac), QKeyCode "ac_home", number 0xb2 +XF86HomePage 0xb2 + +# evdev 173 (0xad), QKeyCode "ac_refresh", number 0xe7 +XF86Reload 0xe7 + +# evdev 174 (0xae): no evdev -> QKeyCode mapping (xkb keysym XF86Close) + +# evdev 175 (0xaf): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 176 (0xb0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 177 (0xb1): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollUp) + +# evdev 178 (0xb2): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollDown) + +# evdev 179 (0xb3): no evdev -> QKeyCode mapping (xkb keysym parenleft) + +# evdev 180 (0xb4): no evdev -> QKeyCode mapping (xkb keysym parenright) + +# evdev 181 (0xb5): no evdev -> QKeyCode mapping (xkb keysym XF86New) + +# evdev 182 (0xb6): no evdev -> QKeyCode mapping (xkb keysym Redo) + +# evdev 183 (0xb7): no evdev -> QKeyCode mapping (xkb keysym XF86Tools) + +# evdev 184 (0xb8): no evdev -> QKeyCode mapping (xkb keysym XF86Launch5) + +# evdev 185 (0xb9): no evdev -> QKeyCode mapping (xkb keysym XF86Launch6) + +# evdev 186 (0xba): no evdev -> QKeyCode mapping (xkb keysym XF86Launch7) + +# evdev 187 (0xbb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch8) + +# evdev 188 (0xbc): no evdev -> QKeyCode mapping (xkb keysym XF86Launch9) + +# evdev 189 (0xbd): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 190 (0xbe): no evdev -> QKeyCode mapping (xkb keysym XF86AudioMicMute) + +# evdev 191 (0xbf): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadToggle) + +# evdev 192 (0xc0): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOn) + +# evdev 193 (0xc1): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOff) + +# evdev 194 (0xc2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 195 (0xc3): no evdev -> QKeyCode mapping (xkb keysym Mode_switch) + +# evdev 196 (0xc4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 197 (0xc5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 198 (0xc6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 199 (0xc7): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 200 (0xc8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay) + +# evdev 201 (0xc9): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPause) + +# evdev 202 (0xca): no evdev -> QKeyCode mapping (xkb keysym XF86Launch3) + +# evdev 203 (0xcb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch4) + +# evdev 204 (0xcc): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchB) + +# evdev 205 (0xcd): no evdev -> QKeyCode mapping (xkb keysym XF86Suspend) + +# evdev 206 (0xce): no evdev -> QKeyCode mapping (xkb keysym XF86Close) + +# evdev 207 (0xcf): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay) + +# evdev 208 (0xd0): no evdev -> QKeyCode mapping (xkb keysym XF86AudioForward) + +# evdev 209 (0xd1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 210 (0xd2): no evdev -> QKeyCode mapping (xkb keysym Print) + +# evdev 211 (0xd3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 212 (0xd4): no evdev -> QKeyCode mapping (xkb keysym XF86WebCam) + +# evdev 213 (0xd5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 214 (0xd6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 215 (0xd7): no evdev -> QKeyCode mapping (xkb keysym XF86Mail) + +# evdev 216 (0xd8): no evdev -> QKeyCode mapping (xkb keysym XF86Messenger) + +# evdev 217 (0xd9): no evdev -> QKeyCode mapping (xkb keysym XF86Search) + +# evdev 218 (0xda): no evdev -> QKeyCode mapping (xkb keysym XF86Go) + +# evdev 219 (0xdb): no evdev -> QKeyCode mapping (xkb keysym XF86Finance) + +# evdev 220 (0xdc): no evdev -> QKeyCode mapping (xkb keysym XF86Game) + +# evdev 221 (0xdd): no evdev -> QKeyCode mapping (xkb keysym XF86Shop) + +# evdev 222 (0xde): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 223 (0xdf): no evdev -> QKeyCode mapping (xkb keysym Cancel) + +# evdev 224 (0xe0): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessDown) + +# evdev 225 (0xe1): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessUp) + +# evdev 226 (0xe2), QKeyCode "mediaselect", number 0xed +XF86AudioMedia 0xed + +# evdev 227 (0xe3): no evdev -> QKeyCode mapping (xkb keysym XF86Display) + +# evdev 228 (0xe4): no evdev -> QKeyCode mapping (xkb keysym XF86KbdLightOnOff) + +# evdev 229 (0xe5): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessDown) + +# evdev 230 (0xe6): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessUp) + +# evdev 231 (0xe7): no evdev -> QKeyCode mapping (xkb keysym XF86Send) + +# evdev 232 (0xe8): no evdev -> QKeyCode mapping (xkb keysym XF86Reply) + +# evdev 233 (0xe9): no evdev -> QKeyCode mapping (xkb keysym XF86MailForward) + +# evdev 234 (0xea): no evdev -> QKeyCode mapping (xkb keysym XF86Save) + +# evdev 235 (0xeb): no evdev -> QKeyCode mapping (xkb keysym XF86Documents) + +# evdev 236 (0xec): no evdev -> QKeyCode mapping (xkb keysym XF86Battery) + +# evdev 237 (0xed): no evdev -> QKeyCode mapping (xkb keysym XF86Bluetooth) + +# evdev 238 (0xee): no evdev -> QKeyCode mapping (xkb keysym XF86WLAN) + +# evdev 239 (0xef): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 240 (0xf0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 241 (0xf1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 242 (0xf2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 243 (0xf3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 244 (0xf4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 245 (0xf5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 246 (0xf6): no evdev -> QKeyCode mapping (xkb keysym Invalid) + +# evdev 247 (0xf7): no evdev -> QKeyCode mapping (xkb keysym Invalid) + +# +# quirks section start +# +# Sometimes multiple keysyms map to the same keycodes. +# The keycode -> keysym lookup finds only one of the +# keysyms. So append them here. +# + +Print 0x54 +Sys_Req 0x54 +Execute 0x54 +KP_Decimal 0x53 numlock +KP_Separator 0x53 numlock +Alt_R 0xb8 +ISO_Level3_Shift 0xb8 +Mode_switch 0xb8 + +# quirks section end diff --git a/app/src/main/assets/roms/keymaps/fr-ch b/app/src/main/assets/roms/keymaps/fr-ch new file mode 100644 index 0000000..bdd944d --- /dev/null +++ b/app/src/main/assets/roms/keymaps/fr-ch @@ -0,0 +1,842 @@ +# +# generated by qemu-keymap +# model : pc105 +# layout : ch +# variant : fr +# options : - + +# name: "French (Switzerland)" + +# modifiers +# 0: Shift +# 1: Lock +# 2: Control +# 3: Mod1 +# 4: Mod2 +# 5: Mod3 +# 6: Mod4 +# 7: Mod5 +# 8: NumLock +# 9: Alt +# 10: LevelThree +# 11: LAlt +# 12: RAlt +# 13: RControl +# 14: LControl +# 15: ScrollLock +# 16: LevelFive +# 17: AltGr +# 18: Meta +# 19: Super +# 20: Hyper + +# evdev 1 (0x1), QKeyCode "esc", number 0x1 +Escape 0x01 + +# evdev 2 (0x2), QKeyCode "1", number 0x2 +1 0x02 +plus 0x02 shift +bar 0x02 altgr +exclamdown 0x02 shift altgr + +# evdev 3 (0x3), QKeyCode "2", number 0x3 +2 0x03 +quotedbl 0x03 shift +at 0x03 altgr +oneeighth 0x03 shift altgr + +# evdev 4 (0x4), QKeyCode "3", number 0x4 +3 0x04 +asterisk 0x04 shift +numbersign 0x04 altgr +sterling 0x04 shift altgr + +# evdev 5 (0x5), QKeyCode "4", number 0x5 +4 0x05 +ccedilla 0x05 shift +onequarter 0x05 altgr +dollar 0x05 shift altgr + +# evdev 6 (0x6), QKeyCode "5", number 0x6 +5 0x06 +percent 0x06 shift +onehalf 0x06 altgr +threeeighths 0x06 shift altgr + +# evdev 7 (0x7), QKeyCode "6", number 0x7 +6 0x07 +ampersand 0x07 shift +notsign 0x07 altgr +fiveeighths 0x07 shift altgr + +# evdev 8 (0x8), QKeyCode "7", number 0x8 +7 0x08 +slash 0x08 shift +bar 0x08 altgr +seveneighths 0x08 shift altgr + +# evdev 9 (0x9), QKeyCode "8", number 0x9 +8 0x09 +parenleft 0x09 shift +cent 0x09 altgr +trademark 0x09 shift altgr + +# evdev 10 (0xa), QKeyCode "9", number 0xa +9 0x0a +parenright 0x0a shift +bracketright 0x0a altgr +plusminus 0x0a shift altgr + +# evdev 11 (0xb), QKeyCode "0", number 0xb +0 0x0b +equal 0x0b shift +braceright 0x0b altgr +degree 0x0b shift altgr + +# evdev 12 (0xc), QKeyCode "minus", number 0xc +apostrophe 0x0c +question 0x0c shift +dead_acute 0x0c altgr +questiondown 0x0c shift altgr + +# evdev 13 (0xd), QKeyCode "equal", number 0xd +dead_circumflex 0x0d +dead_grave 0x0d shift +dead_tilde 0x0d altgr +dead_ogonek 0x0d shift altgr + +# evdev 14 (0xe), QKeyCode "backspace", number 0xe +BackSpace 0x0e + +# evdev 15 (0xf), QKeyCode "tab", number 0xf +Tab 0x0f +ISO_Left_Tab 0x0f shift + +# evdev 16 (0x10), QKeyCode "q", number 0x10 +q 0x10 +Q 0x10 shift +at 0x10 altgr +Greek_OMEGA 0x10 shift altgr + +# evdev 17 (0x11), QKeyCode "w", number 0x11 +w 0x11 +W 0x11 shift +lstroke 0x11 altgr +Lstroke 0x11 shift altgr + +# evdev 18 (0x12), QKeyCode "e", number 0x12 +e 0x12 +E 0x12 shift +EuroSign 0x12 altgr + +# evdev 19 (0x13), QKeyCode "r", number 0x13 +r 0x13 +R 0x13 shift +paragraph 0x13 altgr +registered 0x13 shift altgr + +# evdev 20 (0x14), QKeyCode "t", number 0x14 +t 0x14 +T 0x14 shift +tslash 0x14 altgr +Tslash 0x14 shift altgr + +# evdev 21 (0x15), QKeyCode "y", number 0x15 +z 0x15 +Z 0x15 shift +leftarrow 0x15 altgr +yen 0x15 shift altgr + +# evdev 22 (0x16), QKeyCode "u", number 0x16 +u 0x16 +U 0x16 shift +downarrow 0x16 altgr +uparrow 0x16 shift altgr + +# evdev 23 (0x17), QKeyCode "i", number 0x17 +i 0x17 +I 0x17 shift +rightarrow 0x17 altgr +idotless 0x17 shift altgr + +# evdev 24 (0x18), QKeyCode "o", number 0x18 +o 0x18 +O 0x18 shift +oe 0x18 altgr +OE 0x18 shift altgr + +# evdev 25 (0x19), QKeyCode "p", number 0x19 +p 0x19 +P 0x19 shift +thorn 0x19 altgr +THORN 0x19 shift altgr + +# evdev 26 (0x1a), QKeyCode "bracket_left", number 0x1a +egrave 0x1a +udiaeresis 0x1a shift +bracketleft 0x1a altgr +dead_abovering 0x1a shift altgr + +# evdev 27 (0x1b), QKeyCode "bracket_right", number 0x1b +dead_diaeresis 0x1b +exclam 0x1b shift +bracketright 0x1b altgr +dead_macron 0x1b shift altgr + +# evdev 28 (0x1c), QKeyCode "ret", number 0x1c +Return 0x1c + +# evdev 29 (0x1d), QKeyCode "ctrl", number 0x1d +Control_L 0x1d + +# evdev 30 (0x1e), QKeyCode "a", number 0x1e +a 0x1e +A 0x1e shift +ae 0x1e altgr +AE 0x1e shift altgr + +# evdev 31 (0x1f), QKeyCode "s", number 0x1f +s 0x1f +S 0x1f shift +ssharp 0x1f altgr +section 0x1f shift altgr + +# evdev 32 (0x20), QKeyCode "d", number 0x20 +d 0x20 +D 0x20 shift +eth 0x20 altgr +ETH 0x20 shift altgr + +# evdev 33 (0x21), QKeyCode "f", number 0x21 +f 0x21 +F 0x21 shift +dstroke 0x21 altgr +ordfeminine 0x21 shift altgr + +# evdev 34 (0x22), QKeyCode "g", number 0x22 +g 0x22 +G 0x22 shift +eng 0x22 altgr +ENG 0x22 shift altgr + +# evdev 35 (0x23), QKeyCode "h", number 0x23 +h 0x23 +H 0x23 shift +hstroke 0x23 altgr +Hstroke 0x23 shift altgr + +# evdev 36 (0x24), QKeyCode "j", number 0x24 +j 0x24 +J 0x24 shift +dead_hook 0x24 altgr +dead_horn 0x24 shift altgr + +# evdev 37 (0x25), QKeyCode "k", number 0x25 +k 0x25 +K 0x25 shift +kra 0x25 altgr +ampersand 0x25 shift altgr + +# evdev 38 (0x26), QKeyCode "l", number 0x26 +l 0x26 +L 0x26 shift +lstroke 0x26 altgr +Lstroke 0x26 shift altgr + +# evdev 39 (0x27), QKeyCode "semicolon", number 0x27 +eacute 0x27 +odiaeresis 0x27 shift +dead_acute 0x27 altgr +dead_doubleacute 0x27 shift altgr + +# evdev 40 (0x28), QKeyCode "apostrophe", number 0x28 +agrave 0x28 +adiaeresis 0x28 shift +braceleft 0x28 altgr +dead_caron 0x28 shift altgr + +# evdev 41 (0x29), QKeyCode "grave_accent", number 0x29 +section 0x29 +degree 0x29 shift +notsign 0x29 altgr + +# evdev 42 (0x2a), QKeyCode "shift", number 0x2a +Shift_L 0x2a + +# evdev 43 (0x2b), QKeyCode "backslash", number 0x2b +dollar 0x2b +sterling 0x2b shift +braceright 0x2b altgr +dead_breve 0x2b shift altgr + +# evdev 44 (0x2c), QKeyCode "z", number 0x2c +y 0x2c +Y 0x2c shift +guillemotleft 0x2c altgr +less 0x2c shift altgr + +# evdev 45 (0x2d), QKeyCode "x", number 0x2d +x 0x2d +X 0x2d shift +guillemotright 0x2d altgr +greater 0x2d shift altgr + +# evdev 46 (0x2e), QKeyCode "c", number 0x2e +c 0x2e +C 0x2e shift +cent 0x2e altgr +copyright 0x2e shift altgr + +# evdev 47 (0x2f), QKeyCode "v", number 0x2f +v 0x2f +V 0x2f shift +leftdoublequotemark 0x2f altgr +leftsinglequotemark 0x2f shift altgr + +# evdev 48 (0x30), QKeyCode "b", number 0x30 +b 0x30 +B 0x30 shift +rightdoublequotemark 0x30 altgr +rightsinglequotemark 0x30 shift altgr + +# evdev 49 (0x31), QKeyCode "n", number 0x31 +n 0x31 +N 0x31 shift + +# evdev 50 (0x32), QKeyCode "m", number 0x32 +m 0x32 +M 0x32 shift +mu 0x32 altgr +masculine 0x32 shift altgr + +# evdev 51 (0x33), QKeyCode "comma", number 0x33 +comma 0x33 +semicolon 0x33 shift +horizconnector 0x33 altgr +multiply 0x33 shift altgr + +# evdev 52 (0x34), QKeyCode "dot", number 0x34 +period 0x34 +colon 0x34 shift +periodcentered 0x34 altgr +division 0x34 shift altgr + +# evdev 53 (0x35), QKeyCode "slash", number 0x35 +minus 0x35 +underscore 0x35 shift +dead_belowdot 0x35 altgr +dead_abovedot 0x35 shift altgr + +# evdev 54 (0x36), QKeyCode "shift_r", number 0x36 +Shift_R 0x36 + +# evdev 55 (0x37), QKeyCode "kp_multiply", number 0x37 +KP_Multiply 0x37 + +# evdev 56 (0x38), QKeyCode "alt", number 0x38 +Alt_L 0x38 +Meta_L 0x38 shift + +# evdev 57 (0x39), QKeyCode "spc", number 0x39 +space 0x39 + +# evdev 58 (0x3a), QKeyCode "caps_lock", number 0x3a +Caps_Lock 0x3a + +# evdev 59 (0x3b), QKeyCode "f1", number 0x3b +F1 0x3b + +# evdev 60 (0x3c), QKeyCode "f2", number 0x3c +F2 0x3c + +# evdev 61 (0x3d), QKeyCode "f3", number 0x3d +F3 0x3d + +# evdev 62 (0x3e), QKeyCode "f4", number 0x3e +F4 0x3e + +# evdev 63 (0x3f), QKeyCode "f5", number 0x3f +F5 0x3f + +# evdev 64 (0x40), QKeyCode "f6", number 0x40 +F6 0x40 + +# evdev 65 (0x41), QKeyCode "f7", number 0x41 +F7 0x41 + +# evdev 66 (0x42), QKeyCode "f8", number 0x42 +F8 0x42 + +# evdev 67 (0x43), QKeyCode "f9", number 0x43 +F9 0x43 + +# evdev 68 (0x44), QKeyCode "f10", number 0x44 +F10 0x44 + +# evdev 69 (0x45), QKeyCode "num_lock", number 0x45 +Num_Lock 0x45 + +# evdev 70 (0x46), QKeyCode "scroll_lock", number 0x46 +Scroll_Lock 0x46 + +# evdev 71 (0x47), QKeyCode "kp_7", number 0x47 +KP_Home 0x47 +KP_7 0x47 numlock + +# evdev 72 (0x48), QKeyCode "kp_8", number 0x48 +KP_Up 0x48 +KP_8 0x48 numlock + +# evdev 73 (0x49), QKeyCode "kp_9", number 0x49 +KP_Prior 0x49 +KP_9 0x49 numlock + +# evdev 74 (0x4a), QKeyCode "kp_subtract", number 0x4a +KP_Subtract 0x4a + +# evdev 75 (0x4b), QKeyCode "kp_4", number 0x4b +KP_Left 0x4b +KP_4 0x4b numlock + +# evdev 76 (0x4c), QKeyCode "kp_5", number 0x4c +KP_Begin 0x4c +KP_5 0x4c numlock + +# evdev 77 (0x4d), QKeyCode "kp_6", number 0x4d +KP_Right 0x4d +KP_6 0x4d numlock + +# evdev 78 (0x4e), QKeyCode "kp_add", number 0x4e +KP_Add 0x4e + +# evdev 79 (0x4f), QKeyCode "kp_1", number 0x4f +KP_End 0x4f +KP_1 0x4f numlock + +# evdev 80 (0x50), QKeyCode "kp_2", number 0x50 +KP_Down 0x50 +KP_2 0x50 numlock + +# evdev 81 (0x51), QKeyCode "kp_3", number 0x51 +KP_Next 0x51 +KP_3 0x51 numlock + +# evdev 82 (0x52), QKeyCode "kp_0", number 0x52 +KP_Insert 0x52 +KP_0 0x52 numlock + +# evdev 83 (0x53), QKeyCode "kp_decimal", number 0x53 +KP_Delete 0x53 +KP_Decimal 0x53 numlock + +# evdev 84 (0x54): no evdev -> QKeyCode mapping (xkb keysym ISO_Level3_Shift) + +# evdev 85 (0x55): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 86 (0x56), QKeyCode "less", number 0x56 +less 0x56 +greater 0x56 shift +backslash 0x56 altgr +brokenbar 0x56 shift altgr + +# evdev 87 (0x57), QKeyCode "f11", number 0x57 +F11 0x57 + +# evdev 88 (0x58), QKeyCode "f12", number 0x58 +F12 0x58 + +# evdev 89 (0x59), QKeyCode "ro", number 0x73 + +# evdev 90 (0x5a): no evdev -> QKeyCode mapping (xkb keysym Katakana) + +# evdev 91 (0x5b), QKeyCode "hiragana", number 0x77 +Hiragana 0x77 + +# evdev 92 (0x5c), QKeyCode "henkan", number 0x79 +Henkan_Mode 0x79 + +# evdev 93 (0x5d), QKeyCode "katakanahiragana", number 0x70 +Hiragana_Katakana 0x70 + +# evdev 94 (0x5e), QKeyCode "muhenkan", number 0x7b +Muhenkan 0x7b + +# evdev 95 (0x5f): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 96 (0x60), QKeyCode "kp_enter", number 0x9c +KP_Enter 0x9c + +# evdev 97 (0x61), QKeyCode "ctrl_r", number 0x9d +Control_R 0x9d + +# evdev 98 (0x62), QKeyCode "kp_divide", number 0xb5 +KP_Divide 0xb5 + +# evdev 99 (0x63), QKeyCode "sysrq", number 0x54 +Print 0x54 + +# evdev 100 (0x64), QKeyCode "alt_r", number 0xb8 +ISO_Level3_Shift 0xb8 + +# evdev 101 (0x65), QKeyCode "lf", number 0x5b +Linefeed 0x5b + +# evdev 102 (0x66), QKeyCode "home", number 0xc7 +Home 0xc7 + +# evdev 103 (0x67), QKeyCode "up", number 0xc8 +Up 0xc8 + +# evdev 104 (0x68), QKeyCode "pgup", number 0xc9 +Prior 0xc9 + +# evdev 105 (0x69), QKeyCode "left", number 0xcb +Left 0xcb + +# evdev 106 (0x6a), QKeyCode "right", number 0xcd +Right 0xcd + +# evdev 107 (0x6b), QKeyCode "end", number 0xcf +End 0xcf + +# evdev 108 (0x6c), QKeyCode "down", number 0xd0 +Down 0xd0 + +# evdev 109 (0x6d), QKeyCode "pgdn", number 0xd1 +Next 0xd1 + +# evdev 110 (0x6e), QKeyCode "insert", number 0xd2 +Insert 0xd2 + +# evdev 111 (0x6f), QKeyCode "delete", number 0xd3 +Delete 0xd3 + +# evdev 112 (0x70): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 113 (0x71), QKeyCode "audiomute", number 0xa0 +XF86AudioMute 0xa0 + +# evdev 114 (0x72), QKeyCode "volumedown", number 0xae +XF86AudioLowerVolume 0xae + +# evdev 115 (0x73), QKeyCode "volumeup", number 0xb0 +XF86AudioRaiseVolume 0xb0 + +# evdev 116 (0x74), QKeyCode "power", number 0xde +XF86PowerOff 0xde + +# evdev 117 (0x75), QKeyCode "kp_equals", number 0x59 +KP_Equal 0x59 + +# evdev 118 (0x76): no evdev -> QKeyCode mapping (xkb keysym plusminus) + +# evdev 119 (0x77), QKeyCode "pause", number 0xc6 +Pause 0xc6 + +# evdev 120 (0x78): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchA) + +# evdev 121 (0x79), QKeyCode "kp_comma", number 0x7e +KP_Decimal 0x7e + +# evdev 122 (0x7a): no evdev -> QKeyCode mapping (xkb keysym Hangul) + +# evdev 123 (0x7b): no evdev -> QKeyCode mapping (xkb keysym Hangul_Hanja) + +# evdev 124 (0x7c), QKeyCode "yen", number 0x7d + +# evdev 125 (0x7d), QKeyCode "meta_l", number 0xdb +Super_L 0xdb + +# evdev 126 (0x7e), QKeyCode "meta_r", number 0xdc +Super_R 0xdc + +# evdev 127 (0x7f), QKeyCode "compose", number 0xdd +Menu 0xdd + +# evdev 128 (0x80), QKeyCode "stop", number 0xe8 +Cancel 0xe8 + +# evdev 129 (0x81), QKeyCode "again", number 0x85 +Redo 0x85 + +# evdev 130 (0x82), QKeyCode "props", number 0x86 +SunProps 0x86 + +# evdev 131 (0x83), QKeyCode "undo", number 0x87 +Undo 0x87 + +# evdev 132 (0x84), QKeyCode "front", number 0x8c +SunFront 0x8c + +# evdev 133 (0x85), QKeyCode "copy", number 0xf8 +XF86Copy 0xf8 + +# evdev 134 (0x86), QKeyCode "open", number 0x64 +XF86Open 0x64 + +# evdev 135 (0x87), QKeyCode "paste", number 0x65 +XF86Paste 0x65 + +# evdev 136 (0x88), QKeyCode "find", number 0xc1 +Find 0xc1 + +# evdev 137 (0x89), QKeyCode "cut", number 0xbc +XF86Cut 0xbc + +# evdev 138 (0x8a), QKeyCode "help", number 0xf5 +Help 0xf5 + +# evdev 139 (0x8b), QKeyCode "menu", number 0x9e +XF86MenuKB 0x9e + +# evdev 140 (0x8c), QKeyCode "calculator", number 0xa1 +XF86Calculator 0xa1 + +# evdev 141 (0x8d): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 142 (0x8e), QKeyCode "sleep", number 0xdf +XF86Sleep 0xdf + +# evdev 143 (0x8f), QKeyCode "wake", number 0xe3 +XF86WakeUp 0xe3 + +# evdev 144 (0x90): no evdev -> QKeyCode mapping (xkb keysym XF86Explorer) + +# evdev 145 (0x91): no evdev -> QKeyCode mapping (xkb keysym XF86Send) + +# evdev 146 (0x92): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 147 (0x93): no evdev -> QKeyCode mapping (xkb keysym XF86Xfer) + +# evdev 148 (0x94): no evdev -> QKeyCode mapping (xkb keysym XF86Launch1) + +# evdev 149 (0x95): no evdev -> QKeyCode mapping (xkb keysym XF86Launch2) + +# evdev 150 (0x96): no evdev -> QKeyCode mapping (xkb keysym XF86WWW) + +# evdev 151 (0x97): no evdev -> QKeyCode mapping (xkb keysym XF86DOS) + +# evdev 152 (0x98): no evdev -> QKeyCode mapping (xkb keysym XF86ScreenSaver) + +# evdev 153 (0x99): no evdev -> QKeyCode mapping (xkb keysym XF86RotateWindows) + +# evdev 154 (0x9a): no evdev -> QKeyCode mapping (xkb keysym XF86TaskPane) + +# evdev 155 (0x9b), QKeyCode "mail", number 0xec +XF86Mail 0xec + +# evdev 156 (0x9c), QKeyCode "ac_bookmarks", number 0xe6 +XF86Favorites 0xe6 + +# evdev 157 (0x9d), QKeyCode "computer", number 0xeb +XF86MyComputer 0xeb + +# evdev 158 (0x9e), QKeyCode "ac_back", number 0xea +XF86Back 0xea + +# evdev 159 (0x9f), QKeyCode "ac_forward", number 0xe9 +XF86Forward 0xe9 + +# evdev 160 (0xa0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 161 (0xa1): no evdev -> QKeyCode mapping (xkb keysym XF86Eject) + +# evdev 162 (0xa2): no evdev -> QKeyCode mapping (xkb keysym XF86Eject) + +# evdev 163 (0xa3), QKeyCode "audionext", number 0x99 +XF86AudioNext 0x99 + +# evdev 164 (0xa4), QKeyCode "audioplay", number 0xa2 +XF86AudioPlay 0xa2 +XF86AudioPause 0xa2 shift + +# evdev 165 (0xa5), QKeyCode "audioprev", number 0x90 +XF86AudioPrev 0x90 + +# evdev 166 (0xa6), QKeyCode "audiostop", number 0xa4 +XF86AudioStop 0xa4 +XF86Eject 0xa4 shift + +# evdev 167 (0xa7): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRecord) + +# evdev 168 (0xa8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRewind) + +# evdev 169 (0xa9): no evdev -> QKeyCode mapping (xkb keysym XF86Phone) + +# evdev 170 (0xaa): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 171 (0xab): no evdev -> QKeyCode mapping (xkb keysym XF86Tools) + +# evdev 172 (0xac), QKeyCode "ac_home", number 0xb2 +XF86HomePage 0xb2 + +# evdev 173 (0xad), QKeyCode "ac_refresh", number 0xe7 +XF86Reload 0xe7 + +# evdev 174 (0xae): no evdev -> QKeyCode mapping (xkb keysym XF86Close) + +# evdev 175 (0xaf): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 176 (0xb0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 177 (0xb1): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollUp) + +# evdev 178 (0xb2): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollDown) + +# evdev 179 (0xb3): no evdev -> QKeyCode mapping (xkb keysym parenleft) + +# evdev 180 (0xb4): no evdev -> QKeyCode mapping (xkb keysym parenright) + +# evdev 181 (0xb5): no evdev -> QKeyCode mapping (xkb keysym XF86New) + +# evdev 182 (0xb6): no evdev -> QKeyCode mapping (xkb keysym Redo) + +# evdev 183 (0xb7): no evdev -> QKeyCode mapping (xkb keysym XF86Tools) + +# evdev 184 (0xb8): no evdev -> QKeyCode mapping (xkb keysym XF86Launch5) + +# evdev 185 (0xb9): no evdev -> QKeyCode mapping (xkb keysym XF86Launch6) + +# evdev 186 (0xba): no evdev -> QKeyCode mapping (xkb keysym XF86Launch7) + +# evdev 187 (0xbb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch8) + +# evdev 188 (0xbc): no evdev -> QKeyCode mapping (xkb keysym XF86Launch9) + +# evdev 189 (0xbd): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 190 (0xbe): no evdev -> QKeyCode mapping (xkb keysym XF86AudioMicMute) + +# evdev 191 (0xbf): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadToggle) + +# evdev 192 (0xc0): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOn) + +# evdev 193 (0xc1): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOff) + +# evdev 194 (0xc2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 195 (0xc3): no evdev -> QKeyCode mapping (xkb keysym Mode_switch) + +# evdev 196 (0xc4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 197 (0xc5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 198 (0xc6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 199 (0xc7): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 200 (0xc8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay) + +# evdev 201 (0xc9): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPause) + +# evdev 202 (0xca): no evdev -> QKeyCode mapping (xkb keysym XF86Launch3) + +# evdev 203 (0xcb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch4) + +# evdev 204 (0xcc): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchB) + +# evdev 205 (0xcd): no evdev -> QKeyCode mapping (xkb keysym XF86Suspend) + +# evdev 206 (0xce): no evdev -> QKeyCode mapping (xkb keysym XF86Close) + +# evdev 207 (0xcf): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay) + +# evdev 208 (0xd0): no evdev -> QKeyCode mapping (xkb keysym XF86AudioForward) + +# evdev 209 (0xd1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 210 (0xd2): no evdev -> QKeyCode mapping (xkb keysym Print) + +# evdev 211 (0xd3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 212 (0xd4): no evdev -> QKeyCode mapping (xkb keysym XF86WebCam) + +# evdev 213 (0xd5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 214 (0xd6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 215 (0xd7): no evdev -> QKeyCode mapping (xkb keysym XF86Mail) + +# evdev 216 (0xd8): no evdev -> QKeyCode mapping (xkb keysym XF86Messenger) + +# evdev 217 (0xd9): no evdev -> QKeyCode mapping (xkb keysym XF86Search) + +# evdev 218 (0xda): no evdev -> QKeyCode mapping (xkb keysym XF86Go) + +# evdev 219 (0xdb): no evdev -> QKeyCode mapping (xkb keysym XF86Finance) + +# evdev 220 (0xdc): no evdev -> QKeyCode mapping (xkb keysym XF86Game) + +# evdev 221 (0xdd): no evdev -> QKeyCode mapping (xkb keysym XF86Shop) + +# evdev 222 (0xde): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 223 (0xdf): no evdev -> QKeyCode mapping (xkb keysym Cancel) + +# evdev 224 (0xe0): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessDown) + +# evdev 225 (0xe1): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessUp) + +# evdev 226 (0xe2), QKeyCode "mediaselect", number 0xed +XF86AudioMedia 0xed + +# evdev 227 (0xe3): no evdev -> QKeyCode mapping (xkb keysym XF86Display) + +# evdev 228 (0xe4): no evdev -> QKeyCode mapping (xkb keysym XF86KbdLightOnOff) + +# evdev 229 (0xe5): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessDown) + +# evdev 230 (0xe6): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessUp) + +# evdev 231 (0xe7): no evdev -> QKeyCode mapping (xkb keysym XF86Send) + +# evdev 232 (0xe8): no evdev -> QKeyCode mapping (xkb keysym XF86Reply) + +# evdev 233 (0xe9): no evdev -> QKeyCode mapping (xkb keysym XF86MailForward) + +# evdev 234 (0xea): no evdev -> QKeyCode mapping (xkb keysym XF86Save) + +# evdev 235 (0xeb): no evdev -> QKeyCode mapping (xkb keysym XF86Documents) + +# evdev 236 (0xec): no evdev -> QKeyCode mapping (xkb keysym XF86Battery) + +# evdev 237 (0xed): no evdev -> QKeyCode mapping (xkb keysym XF86Bluetooth) + +# evdev 238 (0xee): no evdev -> QKeyCode mapping (xkb keysym XF86WLAN) + +# evdev 239 (0xef): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 240 (0xf0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 241 (0xf1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 242 (0xf2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 243 (0xf3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 244 (0xf4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 245 (0xf5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 246 (0xf6): no evdev -> QKeyCode mapping (xkb keysym Invalid) + +# evdev 247 (0xf7): no evdev -> QKeyCode mapping (xkb keysym Invalid) + +# +# quirks section start +# +# Sometimes multiple keysyms map to the same keycodes. +# The keycode -> keysym lookup finds only one of the +# keysyms. So append them here. +# + +Print 0x54 +Sys_Req 0x54 +Execute 0x54 +KP_Decimal 0x53 numlock +KP_Separator 0x53 numlock +Alt_R 0xb8 +ISO_Level3_Shift 0xb8 +Mode_switch 0xb8 + +# quirks section end diff --git a/app/src/main/assets/roms/keymaps/hr b/app/src/main/assets/roms/keymaps/hr new file mode 100644 index 0000000..252936c --- /dev/null +++ b/app/src/main/assets/roms/keymaps/hr @@ -0,0 +1,843 @@ +# +# generated by qemu-keymap +# model : pc105 +# layout : hr +# variant : - +# options : - + +# name: "Croatian" + +# modifiers +# 0: Shift +# 1: Lock +# 2: Control +# 3: Mod1 +# 4: Mod2 +# 5: Mod3 +# 6: Mod4 +# 7: Mod5 +# 8: NumLock +# 9: Alt +# 10: LevelThree +# 11: LAlt +# 12: RAlt +# 13: RControl +# 14: LControl +# 15: ScrollLock +# 16: LevelFive +# 17: AltGr +# 18: Meta +# 19: Super +# 20: Hyper + +# evdev 1 (0x1), QKeyCode "esc", number 0x1 +Escape 0x01 + +# evdev 2 (0x2), QKeyCode "1", number 0x2 +1 0x02 +exclam 0x02 shift +asciitilde 0x02 altgr +dead_tilde 0x02 shift altgr + +# evdev 3 (0x3), QKeyCode "2", number 0x3 +2 0x03 +quotedbl 0x03 shift +dead_caron 0x03 altgr +caron 0x03 shift altgr + +# evdev 4 (0x4), QKeyCode "3", number 0x4 +3 0x04 +numbersign 0x04 shift +asciicircum 0x04 altgr +dead_circumflex 0x04 shift altgr + +# evdev 5 (0x5), QKeyCode "4", number 0x5 +4 0x05 +dollar 0x05 shift +dead_breve 0x05 altgr +breve 0x05 shift altgr + +# evdev 6 (0x6), QKeyCode "5", number 0x6 +5 0x06 +percent 0x06 shift +degree 0x06 altgr +dead_abovering 0x06 shift altgr + +# evdev 7 (0x7), QKeyCode "6", number 0x7 +6 0x07 +ampersand 0x07 shift +dead_ogonek 0x07 altgr +ogonek 0x07 shift altgr + +# evdev 8 (0x8), QKeyCode "7", number 0x8 +7 0x08 +slash 0x08 shift +grave 0x08 altgr +dead_grave 0x08 shift altgr + +# evdev 9 (0x9), QKeyCode "8", number 0x9 +8 0x09 +parenleft 0x09 shift +dead_abovedot 0x09 altgr +abovedot 0x09 shift altgr + +# evdev 10 (0xa), QKeyCode "9", number 0xa +9 0x0a +parenright 0x0a shift +dead_acute 0x0a altgr +apostrophe 0x0a shift altgr + +# evdev 11 (0xb), QKeyCode "0", number 0xb +0 0x0b +equal 0x0b shift +dead_doubleacute 0x0b altgr +doubleacute 0x0b shift altgr + +# evdev 12 (0xc), QKeyCode "minus", number 0xc +apostrophe 0x0c +question 0x0c shift +dead_diaeresis 0x0c altgr +diaeresis 0x0c shift altgr + +# evdev 13 (0xd), QKeyCode "equal", number 0xd +plus 0x0d +asterisk 0x0d shift +dead_cedilla 0x0d altgr +cedilla 0x0d shift altgr + +# evdev 14 (0xe), QKeyCode "backspace", number 0xe +BackSpace 0x0e + +# evdev 15 (0xf), QKeyCode "tab", number 0xf +Tab 0x0f +ISO_Left_Tab 0x0f shift + +# evdev 16 (0x10), QKeyCode "q", number 0x10 +q 0x10 +Q 0x10 shift +backslash 0x10 altgr +Greek_OMEGA 0x10 shift altgr + +# evdev 17 (0x11), QKeyCode "w", number 0x11 +w 0x11 +W 0x11 shift +bar 0x11 altgr +Lstroke 0x11 shift altgr + +# evdev 18 (0x12), QKeyCode "e", number 0x12 +e 0x12 +E 0x12 shift +EuroSign 0x12 altgr + +# evdev 19 (0x13), QKeyCode "r", number 0x13 +r 0x13 +R 0x13 shift +paragraph 0x13 altgr +registered 0x13 shift altgr + +# evdev 20 (0x14), QKeyCode "t", number 0x14 +t 0x14 +T 0x14 shift +tslash 0x14 altgr +Tslash 0x14 shift altgr + +# evdev 21 (0x15), QKeyCode "y", number 0x15 +z 0x15 +Z 0x15 shift +leftarrow 0x15 altgr +yen 0x15 shift altgr + +# evdev 22 (0x16), QKeyCode "u", number 0x16 +u 0x16 +U 0x16 shift +downarrow 0x16 altgr +uparrow 0x16 shift altgr + +# evdev 23 (0x17), QKeyCode "i", number 0x17 +i 0x17 +I 0x17 shift +rightarrow 0x17 altgr +idotless 0x17 shift altgr + +# evdev 24 (0x18), QKeyCode "o", number 0x18 +o 0x18 +O 0x18 shift +oslash 0x18 altgr +Oslash 0x18 shift altgr + +# evdev 25 (0x19), QKeyCode "p", number 0x19 +p 0x19 +P 0x19 shift +thorn 0x19 altgr +THORN 0x19 shift altgr + +# evdev 26 (0x1a), QKeyCode "bracket_left", number 0x1a +scaron 0x1a +Scaron 0x1a shift +division 0x1a altgr +dead_abovering 0x1a shift altgr + +# evdev 27 (0x1b), QKeyCode "bracket_right", number 0x1b +dstroke 0x1b +Dstroke 0x1b shift +multiply 0x1b altgr +dead_macron 0x1b shift altgr + +# evdev 28 (0x1c), QKeyCode "ret", number 0x1c +Return 0x1c + +# evdev 29 (0x1d), QKeyCode "ctrl", number 0x1d +Control_L 0x1d + +# evdev 30 (0x1e), QKeyCode "a", number 0x1e +a 0x1e +A 0x1e shift +ae 0x1e altgr +AE 0x1e shift altgr + +# evdev 31 (0x1f), QKeyCode "s", number 0x1f +s 0x1f +S 0x1f shift +doublelowquotemark 0x1f altgr +guillemotright 0x1f shift altgr + +# evdev 32 (0x20), QKeyCode "d", number 0x20 +d 0x20 +D 0x20 shift +leftdoublequotemark 0x20 altgr +guillemotleft 0x20 shift altgr + +# evdev 33 (0x21), QKeyCode "f", number 0x21 +f 0x21 +F 0x21 shift +bracketleft 0x21 altgr +ordfeminine 0x21 shift altgr + +# evdev 34 (0x22), QKeyCode "g", number 0x22 +g 0x22 +G 0x22 shift +bracketright 0x22 altgr +ENG 0x22 shift altgr + +# evdev 35 (0x23), QKeyCode "h", number 0x23 +h 0x23 +H 0x23 shift +hstroke 0x23 altgr +Hstroke 0x23 shift altgr + +# evdev 36 (0x24), QKeyCode "j", number 0x24 +j 0x24 +J 0x24 shift +dead_hook 0x24 altgr +dead_horn 0x24 shift altgr + +# evdev 37 (0x25), QKeyCode "k", number 0x25 +k 0x25 +K 0x25 shift +lstroke 0x25 altgr +ampersand 0x25 shift altgr + +# evdev 38 (0x26), QKeyCode "l", number 0x26 +l 0x26 +L 0x26 shift +lstroke 0x26 altgr +Lstroke 0x26 shift altgr + +# evdev 39 (0x27), QKeyCode "semicolon", number 0x27 +ccaron 0x27 +Ccaron 0x27 shift +dead_acute 0x27 altgr +dead_doubleacute 0x27 shift altgr + +# evdev 40 (0x28), QKeyCode "apostrophe", number 0x28 +cacute 0x28 +Cacute 0x28 shift +ssharp 0x28 altgr +dead_caron 0x28 shift altgr + +# evdev 41 (0x29), QKeyCode "grave_accent", number 0x29 +grave 0x29 +asciitilde 0x29 shift +notsign 0x29 altgr + +# evdev 42 (0x2a), QKeyCode "shift", number 0x2a +Shift_L 0x2a + +# evdev 43 (0x2b), QKeyCode "backslash", number 0x2b +zcaron 0x2b +Zcaron 0x2b shift +currency 0x2b altgr +dead_breve 0x2b shift altgr + +# evdev 44 (0x2c), QKeyCode "z", number 0x2c +y 0x2c +Y 0x2c shift +leftsinglequotemark 0x2c altgr +guillemotright 0x2c shift altgr + +# evdev 45 (0x2d), QKeyCode "x", number 0x2d +x 0x2d +X 0x2d shift +rightsinglequotemark 0x2d altgr +guillemotleft 0x2d shift altgr + +# evdev 46 (0x2e), QKeyCode "c", number 0x2e +c 0x2e +C 0x2e shift +cent 0x2e altgr +copyright 0x2e shift altgr + +# evdev 47 (0x2f), QKeyCode "v", number 0x2f +v 0x2f +V 0x2f shift +at 0x2f altgr +grave 0x2f shift altgr + +# evdev 48 (0x30), QKeyCode "b", number 0x30 +b 0x30 +B 0x30 shift +braceleft 0x30 altgr +apostrophe 0x30 shift altgr + +# evdev 49 (0x31), QKeyCode "n", number 0x31 +n 0x31 +N 0x31 shift +braceright 0x31 altgr + +# evdev 50 (0x32), QKeyCode "m", number 0x32 +m 0x32 +M 0x32 shift +asciicircum 0x32 altgr +masculine 0x32 shift altgr + +# evdev 51 (0x33), QKeyCode "comma", number 0x33 +comma 0x33 +semicolon 0x33 shift +less 0x33 altgr +multiply 0x33 shift altgr + +# evdev 52 (0x34), QKeyCode "dot", number 0x34 +period 0x34 +colon 0x34 shift +greater 0x34 altgr +division 0x34 shift altgr + +# evdev 53 (0x35), QKeyCode "slash", number 0x35 +minus 0x35 +underscore 0x35 shift +dead_belowdot 0x35 altgr +dead_abovedot 0x35 shift altgr + +# evdev 54 (0x36), QKeyCode "shift_r", number 0x36 +Shift_R 0x36 + +# evdev 55 (0x37), QKeyCode "kp_multiply", number 0x37 +KP_Multiply 0x37 + +# evdev 56 (0x38), QKeyCode "alt", number 0x38 +Alt_L 0x38 +Meta_L 0x38 shift + +# evdev 57 (0x39), QKeyCode "spc", number 0x39 +space 0x39 + +# evdev 58 (0x3a), QKeyCode "caps_lock", number 0x3a +Caps_Lock 0x3a + +# evdev 59 (0x3b), QKeyCode "f1", number 0x3b +F1 0x3b + +# evdev 60 (0x3c), QKeyCode "f2", number 0x3c +F2 0x3c + +# evdev 61 (0x3d), QKeyCode "f3", number 0x3d +F3 0x3d + +# evdev 62 (0x3e), QKeyCode "f4", number 0x3e +F4 0x3e + +# evdev 63 (0x3f), QKeyCode "f5", number 0x3f +F5 0x3f + +# evdev 64 (0x40), QKeyCode "f6", number 0x40 +F6 0x40 + +# evdev 65 (0x41), QKeyCode "f7", number 0x41 +F7 0x41 + +# evdev 66 (0x42), QKeyCode "f8", number 0x42 +F8 0x42 + +# evdev 67 (0x43), QKeyCode "f9", number 0x43 +F9 0x43 + +# evdev 68 (0x44), QKeyCode "f10", number 0x44 +F10 0x44 + +# evdev 69 (0x45), QKeyCode "num_lock", number 0x45 +Num_Lock 0x45 + +# evdev 70 (0x46), QKeyCode "scroll_lock", number 0x46 +Scroll_Lock 0x46 + +# evdev 71 (0x47), QKeyCode "kp_7", number 0x47 +KP_Home 0x47 +KP_7 0x47 numlock + +# evdev 72 (0x48), QKeyCode "kp_8", number 0x48 +KP_Up 0x48 +KP_8 0x48 numlock + +# evdev 73 (0x49), QKeyCode "kp_9", number 0x49 +KP_Prior 0x49 +KP_9 0x49 numlock + +# evdev 74 (0x4a), QKeyCode "kp_subtract", number 0x4a +KP_Subtract 0x4a + +# evdev 75 (0x4b), QKeyCode "kp_4", number 0x4b +KP_Left 0x4b +KP_4 0x4b numlock + +# evdev 76 (0x4c), QKeyCode "kp_5", number 0x4c +KP_Begin 0x4c +KP_5 0x4c numlock + +# evdev 77 (0x4d), QKeyCode "kp_6", number 0x4d +KP_Right 0x4d +KP_6 0x4d numlock + +# evdev 78 (0x4e), QKeyCode "kp_add", number 0x4e +KP_Add 0x4e + +# evdev 79 (0x4f), QKeyCode "kp_1", number 0x4f +KP_End 0x4f +KP_1 0x4f numlock + +# evdev 80 (0x50), QKeyCode "kp_2", number 0x50 +KP_Down 0x50 +KP_2 0x50 numlock + +# evdev 81 (0x51), QKeyCode "kp_3", number 0x51 +KP_Next 0x51 +KP_3 0x51 numlock + +# evdev 82 (0x52), QKeyCode "kp_0", number 0x52 +KP_Insert 0x52 +KP_0 0x52 numlock + +# evdev 83 (0x53), QKeyCode "kp_decimal", number 0x53 +KP_Delete 0x53 +KP_Separator 0x53 numlock + +# evdev 84 (0x54): no evdev -> QKeyCode mapping (xkb keysym ISO_Level3_Shift) + +# evdev 85 (0x55): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 86 (0x56), QKeyCode "less", number 0x56 +less 0x56 +greater 0x56 shift +bar 0x56 altgr +brokenbar 0x56 shift altgr + +# evdev 87 (0x57), QKeyCode "f11", number 0x57 +F11 0x57 + +# evdev 88 (0x58), QKeyCode "f12", number 0x58 +F12 0x58 + +# evdev 89 (0x59), QKeyCode "ro", number 0x73 + +# evdev 90 (0x5a): no evdev -> QKeyCode mapping (xkb keysym Katakana) + +# evdev 91 (0x5b), QKeyCode "hiragana", number 0x77 +Hiragana 0x77 + +# evdev 92 (0x5c), QKeyCode "henkan", number 0x79 +Henkan_Mode 0x79 + +# evdev 93 (0x5d), QKeyCode "katakanahiragana", number 0x70 +Hiragana_Katakana 0x70 + +# evdev 94 (0x5e), QKeyCode "muhenkan", number 0x7b +Muhenkan 0x7b + +# evdev 95 (0x5f): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 96 (0x60), QKeyCode "kp_enter", number 0x9c +KP_Enter 0x9c + +# evdev 97 (0x61), QKeyCode "ctrl_r", number 0x9d +Control_R 0x9d + +# evdev 98 (0x62), QKeyCode "kp_divide", number 0xb5 +KP_Divide 0xb5 + +# evdev 99 (0x63), QKeyCode "sysrq", number 0x54 +Print 0x54 + +# evdev 100 (0x64), QKeyCode "alt_r", number 0xb8 +ISO_Level3_Shift 0xb8 + +# evdev 101 (0x65), QKeyCode "lf", number 0x5b +Linefeed 0x5b + +# evdev 102 (0x66), QKeyCode "home", number 0xc7 +Home 0xc7 + +# evdev 103 (0x67), QKeyCode "up", number 0xc8 +Up 0xc8 + +# evdev 104 (0x68), QKeyCode "pgup", number 0xc9 +Prior 0xc9 + +# evdev 105 (0x69), QKeyCode "left", number 0xcb +Left 0xcb + +# evdev 106 (0x6a), QKeyCode "right", number 0xcd +Right 0xcd + +# evdev 107 (0x6b), QKeyCode "end", number 0xcf +End 0xcf + +# evdev 108 (0x6c), QKeyCode "down", number 0xd0 +Down 0xd0 + +# evdev 109 (0x6d), QKeyCode "pgdn", number 0xd1 +Next 0xd1 + +# evdev 110 (0x6e), QKeyCode "insert", number 0xd2 +Insert 0xd2 + +# evdev 111 (0x6f), QKeyCode "delete", number 0xd3 +Delete 0xd3 + +# evdev 112 (0x70): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 113 (0x71), QKeyCode "audiomute", number 0xa0 +XF86AudioMute 0xa0 + +# evdev 114 (0x72), QKeyCode "volumedown", number 0xae +XF86AudioLowerVolume 0xae + +# evdev 115 (0x73), QKeyCode "volumeup", number 0xb0 +XF86AudioRaiseVolume 0xb0 + +# evdev 116 (0x74), QKeyCode "power", number 0xde +XF86PowerOff 0xde + +# evdev 117 (0x75), QKeyCode "kp_equals", number 0x59 +KP_Equal 0x59 + +# evdev 118 (0x76): no evdev -> QKeyCode mapping (xkb keysym plusminus) + +# evdev 119 (0x77), QKeyCode "pause", number 0xc6 +Pause 0xc6 + +# evdev 120 (0x78): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchA) + +# evdev 121 (0x79), QKeyCode "kp_comma", number 0x7e +KP_Decimal 0x7e + +# evdev 122 (0x7a): no evdev -> QKeyCode mapping (xkb keysym Hangul) + +# evdev 123 (0x7b): no evdev -> QKeyCode mapping (xkb keysym Hangul_Hanja) + +# evdev 124 (0x7c), QKeyCode "yen", number 0x7d + +# evdev 125 (0x7d), QKeyCode "meta_l", number 0xdb +Super_L 0xdb + +# evdev 126 (0x7e), QKeyCode "meta_r", number 0xdc +Super_R 0xdc + +# evdev 127 (0x7f), QKeyCode "compose", number 0xdd +Menu 0xdd + +# evdev 128 (0x80), QKeyCode "stop", number 0xe8 +Cancel 0xe8 + +# evdev 129 (0x81), QKeyCode "again", number 0x85 +Redo 0x85 + +# evdev 130 (0x82), QKeyCode "props", number 0x86 +SunProps 0x86 + +# evdev 131 (0x83), QKeyCode "undo", number 0x87 +Undo 0x87 + +# evdev 132 (0x84), QKeyCode "front", number 0x8c +SunFront 0x8c + +# evdev 133 (0x85), QKeyCode "copy", number 0xf8 +XF86Copy 0xf8 + +# evdev 134 (0x86), QKeyCode "open", number 0x64 +XF86Open 0x64 + +# evdev 135 (0x87), QKeyCode "paste", number 0x65 +XF86Paste 0x65 + +# evdev 136 (0x88), QKeyCode "find", number 0xc1 +Find 0xc1 + +# evdev 137 (0x89), QKeyCode "cut", number 0xbc +XF86Cut 0xbc + +# evdev 138 (0x8a), QKeyCode "help", number 0xf5 +Help 0xf5 + +# evdev 139 (0x8b), QKeyCode "menu", number 0x9e +XF86MenuKB 0x9e + +# evdev 140 (0x8c), QKeyCode "calculator", number 0xa1 +XF86Calculator 0xa1 + +# evdev 141 (0x8d): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 142 (0x8e), QKeyCode "sleep", number 0xdf +XF86Sleep 0xdf + +# evdev 143 (0x8f), QKeyCode "wake", number 0xe3 +XF86WakeUp 0xe3 + +# evdev 144 (0x90): no evdev -> QKeyCode mapping (xkb keysym XF86Explorer) + +# evdev 145 (0x91): no evdev -> QKeyCode mapping (xkb keysym XF86Send) + +# evdev 146 (0x92): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 147 (0x93): no evdev -> QKeyCode mapping (xkb keysym XF86Xfer) + +# evdev 148 (0x94): no evdev -> QKeyCode mapping (xkb keysym XF86Launch1) + +# evdev 149 (0x95): no evdev -> QKeyCode mapping (xkb keysym XF86Launch2) + +# evdev 150 (0x96): no evdev -> QKeyCode mapping (xkb keysym XF86WWW) + +# evdev 151 (0x97): no evdev -> QKeyCode mapping (xkb keysym XF86DOS) + +# evdev 152 (0x98): no evdev -> QKeyCode mapping (xkb keysym XF86ScreenSaver) + +# evdev 153 (0x99): no evdev -> QKeyCode mapping (xkb keysym XF86RotateWindows) + +# evdev 154 (0x9a): no evdev -> QKeyCode mapping (xkb keysym XF86TaskPane) + +# evdev 155 (0x9b), QKeyCode "mail", number 0xec +XF86Mail 0xec + +# evdev 156 (0x9c), QKeyCode "ac_bookmarks", number 0xe6 +XF86Favorites 0xe6 + +# evdev 157 (0x9d), QKeyCode "computer", number 0xeb +XF86MyComputer 0xeb + +# evdev 158 (0x9e), QKeyCode "ac_back", number 0xea +XF86Back 0xea + +# evdev 159 (0x9f), QKeyCode "ac_forward", number 0xe9 +XF86Forward 0xe9 + +# evdev 160 (0xa0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 161 (0xa1): no evdev -> QKeyCode mapping (xkb keysym XF86Eject) + +# evdev 162 (0xa2): no evdev -> QKeyCode mapping (xkb keysym XF86Eject) + +# evdev 163 (0xa3), QKeyCode "audionext", number 0x99 +XF86AudioNext 0x99 + +# evdev 164 (0xa4), QKeyCode "audioplay", number 0xa2 +XF86AudioPlay 0xa2 +XF86AudioPause 0xa2 shift + +# evdev 165 (0xa5), QKeyCode "audioprev", number 0x90 +XF86AudioPrev 0x90 + +# evdev 166 (0xa6), QKeyCode "audiostop", number 0xa4 +XF86AudioStop 0xa4 +XF86Eject 0xa4 shift + +# evdev 167 (0xa7): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRecord) + +# evdev 168 (0xa8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRewind) + +# evdev 169 (0xa9): no evdev -> QKeyCode mapping (xkb keysym XF86Phone) + +# evdev 170 (0xaa): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 171 (0xab): no evdev -> QKeyCode mapping (xkb keysym XF86Tools) + +# evdev 172 (0xac), QKeyCode "ac_home", number 0xb2 +XF86HomePage 0xb2 + +# evdev 173 (0xad), QKeyCode "ac_refresh", number 0xe7 +XF86Reload 0xe7 + +# evdev 174 (0xae): no evdev -> QKeyCode mapping (xkb keysym XF86Close) + +# evdev 175 (0xaf): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 176 (0xb0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 177 (0xb1): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollUp) + +# evdev 178 (0xb2): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollDown) + +# evdev 179 (0xb3): no evdev -> QKeyCode mapping (xkb keysym parenleft) + +# evdev 180 (0xb4): no evdev -> QKeyCode mapping (xkb keysym parenright) + +# evdev 181 (0xb5): no evdev -> QKeyCode mapping (xkb keysym XF86New) + +# evdev 182 (0xb6): no evdev -> QKeyCode mapping (xkb keysym Redo) + +# evdev 183 (0xb7): no evdev -> QKeyCode mapping (xkb keysym XF86Tools) + +# evdev 184 (0xb8): no evdev -> QKeyCode mapping (xkb keysym XF86Launch5) + +# evdev 185 (0xb9): no evdev -> QKeyCode mapping (xkb keysym XF86Launch6) + +# evdev 186 (0xba): no evdev -> QKeyCode mapping (xkb keysym XF86Launch7) + +# evdev 187 (0xbb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch8) + +# evdev 188 (0xbc): no evdev -> QKeyCode mapping (xkb keysym XF86Launch9) + +# evdev 189 (0xbd): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 190 (0xbe): no evdev -> QKeyCode mapping (xkb keysym XF86AudioMicMute) + +# evdev 191 (0xbf): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadToggle) + +# evdev 192 (0xc0): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOn) + +# evdev 193 (0xc1): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOff) + +# evdev 194 (0xc2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 195 (0xc3): no evdev -> QKeyCode mapping (xkb keysym Mode_switch) + +# evdev 196 (0xc4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 197 (0xc5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 198 (0xc6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 199 (0xc7): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 200 (0xc8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay) + +# evdev 201 (0xc9): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPause) + +# evdev 202 (0xca): no evdev -> QKeyCode mapping (xkb keysym XF86Launch3) + +# evdev 203 (0xcb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch4) + +# evdev 204 (0xcc): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchB) + +# evdev 205 (0xcd): no evdev -> QKeyCode mapping (xkb keysym XF86Suspend) + +# evdev 206 (0xce): no evdev -> QKeyCode mapping (xkb keysym XF86Close) + +# evdev 207 (0xcf): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay) + +# evdev 208 (0xd0): no evdev -> QKeyCode mapping (xkb keysym XF86AudioForward) + +# evdev 209 (0xd1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 210 (0xd2): no evdev -> QKeyCode mapping (xkb keysym Print) + +# evdev 211 (0xd3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 212 (0xd4): no evdev -> QKeyCode mapping (xkb keysym XF86WebCam) + +# evdev 213 (0xd5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 214 (0xd6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 215 (0xd7): no evdev -> QKeyCode mapping (xkb keysym XF86Mail) + +# evdev 216 (0xd8): no evdev -> QKeyCode mapping (xkb keysym XF86Messenger) + +# evdev 217 (0xd9): no evdev -> QKeyCode mapping (xkb keysym XF86Search) + +# evdev 218 (0xda): no evdev -> QKeyCode mapping (xkb keysym XF86Go) + +# evdev 219 (0xdb): no evdev -> QKeyCode mapping (xkb keysym XF86Finance) + +# evdev 220 (0xdc): no evdev -> QKeyCode mapping (xkb keysym XF86Game) + +# evdev 221 (0xdd): no evdev -> QKeyCode mapping (xkb keysym XF86Shop) + +# evdev 222 (0xde): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 223 (0xdf): no evdev -> QKeyCode mapping (xkb keysym Cancel) + +# evdev 224 (0xe0): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessDown) + +# evdev 225 (0xe1): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessUp) + +# evdev 226 (0xe2), QKeyCode "mediaselect", number 0xed +XF86AudioMedia 0xed + +# evdev 227 (0xe3): no evdev -> QKeyCode mapping (xkb keysym XF86Display) + +# evdev 228 (0xe4): no evdev -> QKeyCode mapping (xkb keysym XF86KbdLightOnOff) + +# evdev 229 (0xe5): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessDown) + +# evdev 230 (0xe6): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessUp) + +# evdev 231 (0xe7): no evdev -> QKeyCode mapping (xkb keysym XF86Send) + +# evdev 232 (0xe8): no evdev -> QKeyCode mapping (xkb keysym XF86Reply) + +# evdev 233 (0xe9): no evdev -> QKeyCode mapping (xkb keysym XF86MailForward) + +# evdev 234 (0xea): no evdev -> QKeyCode mapping (xkb keysym XF86Save) + +# evdev 235 (0xeb): no evdev -> QKeyCode mapping (xkb keysym XF86Documents) + +# evdev 236 (0xec): no evdev -> QKeyCode mapping (xkb keysym XF86Battery) + +# evdev 237 (0xed): no evdev -> QKeyCode mapping (xkb keysym XF86Bluetooth) + +# evdev 238 (0xee): no evdev -> QKeyCode mapping (xkb keysym XF86WLAN) + +# evdev 239 (0xef): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 240 (0xf0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 241 (0xf1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 242 (0xf2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 243 (0xf3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 244 (0xf4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 245 (0xf5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 246 (0xf6): no evdev -> QKeyCode mapping (xkb keysym Invalid) + +# evdev 247 (0xf7): no evdev -> QKeyCode mapping (xkb keysym Invalid) + +# +# quirks section start +# +# Sometimes multiple keysyms map to the same keycodes. +# The keycode -> keysym lookup finds only one of the +# keysyms. So append them here. +# + +Print 0x54 +Sys_Req 0x54 +Execute 0x54 +KP_Decimal 0x53 numlock +KP_Separator 0x53 numlock +Alt_R 0xb8 +ISO_Level3_Shift 0xb8 +Mode_switch 0xb8 + +# quirks section end diff --git a/app/src/main/assets/roms/keymaps/hu b/app/src/main/assets/roms/keymaps/hu new file mode 100644 index 0000000..8531476 --- /dev/null +++ b/app/src/main/assets/roms/keymaps/hu @@ -0,0 +1,842 @@ +# +# generated by qemu-keymap +# model : pc105 +# layout : hu +# variant : - +# options : - + +# name: "Hungarian" + +# modifiers +# 0: Shift +# 1: Lock +# 2: Control +# 3: Mod1 +# 4: Mod2 +# 5: Mod3 +# 6: Mod4 +# 7: Mod5 +# 8: NumLock +# 9: Alt +# 10: LevelThree +# 11: LAlt +# 12: RAlt +# 13: RControl +# 14: LControl +# 15: ScrollLock +# 16: LevelFive +# 17: AltGr +# 18: Meta +# 19: Super +# 20: Hyper + +# evdev 1 (0x1), QKeyCode "esc", number 0x1 +Escape 0x01 + +# evdev 2 (0x2), QKeyCode "1", number 0x2 +1 0x02 +apostrophe 0x02 shift +asciitilde 0x02 altgr +dead_tilde 0x02 shift altgr + +# evdev 3 (0x3), QKeyCode "2", number 0x3 +2 0x03 +quotedbl 0x03 shift +dead_caron 0x03 altgr +caron 0x03 shift altgr + +# evdev 4 (0x4), QKeyCode "3", number 0x4 +3 0x04 +plus 0x04 shift +asciicircum 0x04 altgr +dead_circumflex 0x04 shift altgr + +# evdev 5 (0x5), QKeyCode "4", number 0x5 +4 0x05 +exclam 0x05 shift +dead_breve 0x05 altgr +breve 0x05 shift altgr + +# evdev 6 (0x6), QKeyCode "5", number 0x6 +5 0x06 +percent 0x06 shift +dead_abovering 0x06 altgr +degree 0x06 shift altgr + +# evdev 7 (0x7), QKeyCode "6", number 0x7 +6 0x07 +slash 0x07 shift +dead_ogonek 0x07 altgr +ogonek 0x07 shift altgr + +# evdev 8 (0x8), QKeyCode "7", number 0x8 +7 0x08 +equal 0x08 shift +grave 0x08 altgr +dead_grave 0x08 shift altgr + +# evdev 9 (0x9), QKeyCode "8", number 0x9 +8 0x09 +parenleft 0x09 shift +dead_abovedot 0x09 altgr +abovedot 0x09 shift altgr + +# evdev 10 (0xa), QKeyCode "9", number 0xa +9 0x0a +parenright 0x0a shift +dead_acute 0x0a altgr +acute 0x0a shift altgr + +# evdev 11 (0xb), QKeyCode "0", number 0xb +odiaeresis 0x0b +Odiaeresis 0x0b shift +dead_doubleacute 0x0b altgr +doubleacute 0x0b shift altgr + +# evdev 12 (0xc), QKeyCode "minus", number 0xc +udiaeresis 0x0c +Udiaeresis 0x0c shift +dead_diaeresis 0x0c altgr +diaeresis 0x0c shift altgr + +# evdev 13 (0xd), QKeyCode "equal", number 0xd +oacute 0x0d +Oacute 0x0d shift +dead_cedilla 0x0d altgr +cedilla 0x0d shift altgr + +# evdev 14 (0xe), QKeyCode "backspace", number 0xe +BackSpace 0x0e + +# evdev 15 (0xf), QKeyCode "tab", number 0xf +Tab 0x0f +ISO_Left_Tab 0x0f shift + +# evdev 16 (0x10), QKeyCode "q", number 0x10 +q 0x10 +Q 0x10 shift +backslash 0x10 altgr +Greek_OMEGA 0x10 shift altgr + +# evdev 17 (0x11), QKeyCode "w", number 0x11 +w 0x11 +W 0x11 shift +bar 0x11 altgr +Lstroke 0x11 shift altgr + +# evdev 18 (0x12), QKeyCode "e", number 0x12 +e 0x12 +E 0x12 shift +Adiaeresis 0x12 altgr + +# evdev 19 (0x13), QKeyCode "r", number 0x13 +r 0x13 +R 0x13 shift +paragraph 0x13 altgr +registered 0x13 shift altgr + +# evdev 20 (0x14), QKeyCode "t", number 0x14 +t 0x14 +T 0x14 shift +tslash 0x14 altgr +Tslash 0x14 shift altgr + +# evdev 21 (0x15), QKeyCode "y", number 0x15 +z 0x15 +Z 0x15 shift +endash 0x15 altgr +yen 0x15 shift altgr + +# evdev 22 (0x16), QKeyCode "u", number 0x16 +u 0x16 +U 0x16 shift +EuroSign 0x16 altgr +uparrow 0x16 shift altgr + +# evdev 23 (0x17), QKeyCode "i", number 0x17 +i 0x17 +I 0x17 shift +Iacute 0x17 altgr +iacute 0x17 shift altgr + +# evdev 24 (0x18), QKeyCode "o", number 0x18 +o 0x18 +O 0x18 shift +doublelowquotemark 0x18 altgr +Oslash 0x18 shift altgr + +# evdev 25 (0x19), QKeyCode "p", number 0x19 +p 0x19 +P 0x19 shift +rightdoublequotemark 0x19 altgr +THORN 0x19 shift altgr + +# evdev 26 (0x1a), QKeyCode "bracket_left", number 0x1a +odoubleacute 0x1a +Odoubleacute 0x1a shift +division 0x1a altgr +dead_abovering 0x1a shift altgr + +# evdev 27 (0x1b), QKeyCode "bracket_right", number 0x1b +uacute 0x1b +Uacute 0x1b shift +multiply 0x1b altgr +dead_macron 0x1b shift altgr + +# evdev 28 (0x1c), QKeyCode "ret", number 0x1c +Return 0x1c + +# evdev 29 (0x1d), QKeyCode "ctrl", number 0x1d +Control_L 0x1d + +# evdev 30 (0x1e), QKeyCode "a", number 0x1e +a 0x1e +A 0x1e shift +adiaeresis 0x1e altgr +Adiaeresis 0x1e shift altgr + +# evdev 31 (0x1f), QKeyCode "s", number 0x1f +s 0x1f +S 0x1f shift +dstroke 0x1f altgr +section 0x1f shift altgr + +# evdev 32 (0x20), QKeyCode "d", number 0x20 +d 0x20 +D 0x20 shift +Dstroke 0x20 altgr +ETH 0x20 shift altgr + +# evdev 33 (0x21), QKeyCode "f", number 0x21 +f 0x21 +F 0x21 shift +bracketleft 0x21 altgr +ordfeminine 0x21 shift altgr + +# evdev 34 (0x22), QKeyCode "g", number 0x22 +g 0x22 +G 0x22 shift +bracketright 0x22 altgr +ENG 0x22 shift altgr + +# evdev 35 (0x23), QKeyCode "h", number 0x23 +h 0x23 +H 0x23 shift +hstroke 0x23 altgr +Hstroke 0x23 shift altgr + +# evdev 36 (0x24), QKeyCode "j", number 0x24 +j 0x24 +J 0x24 shift +iacute 0x24 altgr +Iacute 0x24 shift altgr + +# evdev 37 (0x25), QKeyCode "k", number 0x25 +k 0x25 +K 0x25 shift +lstroke 0x25 altgr +ampersand 0x25 shift altgr + +# evdev 38 (0x26), QKeyCode "l", number 0x26 +l 0x26 +L 0x26 shift +Lstroke 0x26 altgr + +# evdev 39 (0x27), QKeyCode "semicolon", number 0x27 +eacute 0x27 +Eacute 0x27 shift +dollar 0x27 altgr +cent 0x27 shift altgr + +# evdev 40 (0x28), QKeyCode "apostrophe", number 0x28 +aacute 0x28 +Aacute 0x28 shift +ssharp 0x28 altgr +dead_caron 0x28 shift altgr + +# evdev 41 (0x29), QKeyCode "grave_accent", number 0x29 +0 0x29 +section 0x29 shift +notsign 0x29 altgr + +# evdev 42 (0x2a), QKeyCode "shift", number 0x2a +Shift_L 0x2a + +# evdev 43 (0x2b), QKeyCode "backslash", number 0x2b +udoubleacute 0x2b +Udoubleacute 0x2b shift +currency 0x2b altgr +dead_breve 0x2b shift altgr + +# evdev 44 (0x2c), QKeyCode "z", number 0x2c +y 0x2c +Y 0x2c shift +greater 0x2c altgr +less 0x2c shift altgr + +# evdev 45 (0x2d), QKeyCode "x", number 0x2d +x 0x2d +X 0x2d shift +numbersign 0x2d altgr +greater 0x2d shift altgr + +# evdev 46 (0x2e), QKeyCode "c", number 0x2e +c 0x2e +C 0x2e shift +ampersand 0x2e altgr +copyright 0x2e shift altgr + +# evdev 47 (0x2f), QKeyCode "v", number 0x2f +v 0x2f +V 0x2f shift +at 0x2f altgr +leftsinglequotemark 0x2f shift altgr + +# evdev 48 (0x30), QKeyCode "b", number 0x30 +b 0x30 +B 0x30 shift +braceleft 0x30 altgr +rightsinglequotemark 0x30 shift altgr + +# evdev 49 (0x31), QKeyCode "n", number 0x31 +n 0x31 +N 0x31 shift +braceright 0x31 altgr + +# evdev 50 (0x32), QKeyCode "m", number 0x32 +m 0x32 +M 0x32 shift +less 0x32 altgr +masculine 0x32 shift altgr + +# evdev 51 (0x33), QKeyCode "comma", number 0x33 +comma 0x33 +question 0x33 shift +semicolon 0x33 altgr +multiply 0x33 shift altgr + +# evdev 52 (0x34), QKeyCode "dot", number 0x34 +period 0x34 +colon 0x34 shift +greater 0x34 altgr +division 0x34 shift altgr + +# evdev 53 (0x35), QKeyCode "slash", number 0x35 +minus 0x35 +underscore 0x35 shift +asterisk 0x35 altgr +dead_abovedot 0x35 shift altgr + +# evdev 54 (0x36), QKeyCode "shift_r", number 0x36 +Shift_R 0x36 + +# evdev 55 (0x37), QKeyCode "kp_multiply", number 0x37 +KP_Multiply 0x37 + +# evdev 56 (0x38), QKeyCode "alt", number 0x38 +Alt_L 0x38 +Meta_L 0x38 shift + +# evdev 57 (0x39), QKeyCode "spc", number 0x39 +space 0x39 + +# evdev 58 (0x3a), QKeyCode "caps_lock", number 0x3a +Caps_Lock 0x3a + +# evdev 59 (0x3b), QKeyCode "f1", number 0x3b +F1 0x3b + +# evdev 60 (0x3c), QKeyCode "f2", number 0x3c +F2 0x3c + +# evdev 61 (0x3d), QKeyCode "f3", number 0x3d +F3 0x3d + +# evdev 62 (0x3e), QKeyCode "f4", number 0x3e +F4 0x3e + +# evdev 63 (0x3f), QKeyCode "f5", number 0x3f +F5 0x3f + +# evdev 64 (0x40), QKeyCode "f6", number 0x40 +F6 0x40 + +# evdev 65 (0x41), QKeyCode "f7", number 0x41 +F7 0x41 + +# evdev 66 (0x42), QKeyCode "f8", number 0x42 +F8 0x42 + +# evdev 67 (0x43), QKeyCode "f9", number 0x43 +F9 0x43 + +# evdev 68 (0x44), QKeyCode "f10", number 0x44 +F10 0x44 + +# evdev 69 (0x45), QKeyCode "num_lock", number 0x45 +Num_Lock 0x45 + +# evdev 70 (0x46), QKeyCode "scroll_lock", number 0x46 +Scroll_Lock 0x46 + +# evdev 71 (0x47), QKeyCode "kp_7", number 0x47 +KP_Home 0x47 +KP_7 0x47 numlock + +# evdev 72 (0x48), QKeyCode "kp_8", number 0x48 +KP_Up 0x48 +KP_8 0x48 numlock + +# evdev 73 (0x49), QKeyCode "kp_9", number 0x49 +KP_Prior 0x49 +KP_9 0x49 numlock + +# evdev 74 (0x4a), QKeyCode "kp_subtract", number 0x4a +KP_Subtract 0x4a + +# evdev 75 (0x4b), QKeyCode "kp_4", number 0x4b +KP_Left 0x4b +KP_4 0x4b numlock + +# evdev 76 (0x4c), QKeyCode "kp_5", number 0x4c +KP_Begin 0x4c +KP_5 0x4c numlock + +# evdev 77 (0x4d), QKeyCode "kp_6", number 0x4d +KP_Right 0x4d +KP_6 0x4d numlock + +# evdev 78 (0x4e), QKeyCode "kp_add", number 0x4e +KP_Add 0x4e + +# evdev 79 (0x4f), QKeyCode "kp_1", number 0x4f +KP_End 0x4f +KP_1 0x4f numlock + +# evdev 80 (0x50), QKeyCode "kp_2", number 0x50 +KP_Down 0x50 +KP_2 0x50 numlock + +# evdev 81 (0x51), QKeyCode "kp_3", number 0x51 +KP_Next 0x51 +KP_3 0x51 numlock + +# evdev 82 (0x52), QKeyCode "kp_0", number 0x52 +KP_Insert 0x52 +KP_0 0x52 numlock + +# evdev 83 (0x53), QKeyCode "kp_decimal", number 0x53 +KP_Delete 0x53 +KP_Separator 0x53 numlock + +# evdev 84 (0x54): no evdev -> QKeyCode mapping (xkb keysym ISO_Level3_Shift) + +# evdev 85 (0x55): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 86 (0x56), QKeyCode "less", number 0x56 +iacute 0x56 +Iacute 0x56 shift +less 0x56 altgr +greater 0x56 shift altgr + +# evdev 87 (0x57), QKeyCode "f11", number 0x57 +F11 0x57 + +# evdev 88 (0x58), QKeyCode "f12", number 0x58 +F12 0x58 + +# evdev 89 (0x59), QKeyCode "ro", number 0x73 + +# evdev 90 (0x5a): no evdev -> QKeyCode mapping (xkb keysym Katakana) + +# evdev 91 (0x5b), QKeyCode "hiragana", number 0x77 +Hiragana 0x77 + +# evdev 92 (0x5c), QKeyCode "henkan", number 0x79 +Henkan_Mode 0x79 + +# evdev 93 (0x5d), QKeyCode "katakanahiragana", number 0x70 +Hiragana_Katakana 0x70 + +# evdev 94 (0x5e), QKeyCode "muhenkan", number 0x7b +Muhenkan 0x7b + +# evdev 95 (0x5f): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 96 (0x60), QKeyCode "kp_enter", number 0x9c +KP_Enter 0x9c + +# evdev 97 (0x61), QKeyCode "ctrl_r", number 0x9d +Control_R 0x9d + +# evdev 98 (0x62), QKeyCode "kp_divide", number 0xb5 +KP_Divide 0xb5 + +# evdev 99 (0x63), QKeyCode "sysrq", number 0x54 +Print 0x54 + +# evdev 100 (0x64), QKeyCode "alt_r", number 0xb8 +ISO_Level3_Shift 0xb8 + +# evdev 101 (0x65), QKeyCode "lf", number 0x5b +Linefeed 0x5b + +# evdev 102 (0x66), QKeyCode "home", number 0xc7 +Home 0xc7 + +# evdev 103 (0x67), QKeyCode "up", number 0xc8 +Up 0xc8 + +# evdev 104 (0x68), QKeyCode "pgup", number 0xc9 +Prior 0xc9 + +# evdev 105 (0x69), QKeyCode "left", number 0xcb +Left 0xcb + +# evdev 106 (0x6a), QKeyCode "right", number 0xcd +Right 0xcd + +# evdev 107 (0x6b), QKeyCode "end", number 0xcf +End 0xcf + +# evdev 108 (0x6c), QKeyCode "down", number 0xd0 +Down 0xd0 + +# evdev 109 (0x6d), QKeyCode "pgdn", number 0xd1 +Next 0xd1 + +# evdev 110 (0x6e), QKeyCode "insert", number 0xd2 +Insert 0xd2 + +# evdev 111 (0x6f), QKeyCode "delete", number 0xd3 +Delete 0xd3 + +# evdev 112 (0x70): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 113 (0x71), QKeyCode "audiomute", number 0xa0 +XF86AudioMute 0xa0 + +# evdev 114 (0x72), QKeyCode "volumedown", number 0xae +XF86AudioLowerVolume 0xae + +# evdev 115 (0x73), QKeyCode "volumeup", number 0xb0 +XF86AudioRaiseVolume 0xb0 + +# evdev 116 (0x74), QKeyCode "power", number 0xde +XF86PowerOff 0xde + +# evdev 117 (0x75), QKeyCode "kp_equals", number 0x59 +KP_Equal 0x59 + +# evdev 118 (0x76): no evdev -> QKeyCode mapping (xkb keysym plusminus) + +# evdev 119 (0x77), QKeyCode "pause", number 0xc6 +Pause 0xc6 + +# evdev 120 (0x78): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchA) + +# evdev 121 (0x79), QKeyCode "kp_comma", number 0x7e +KP_Decimal 0x7e + +# evdev 122 (0x7a): no evdev -> QKeyCode mapping (xkb keysym Hangul) + +# evdev 123 (0x7b): no evdev -> QKeyCode mapping (xkb keysym Hangul_Hanja) + +# evdev 124 (0x7c), QKeyCode "yen", number 0x7d + +# evdev 125 (0x7d), QKeyCode "meta_l", number 0xdb +Super_L 0xdb + +# evdev 126 (0x7e), QKeyCode "meta_r", number 0xdc +Super_R 0xdc + +# evdev 127 (0x7f), QKeyCode "compose", number 0xdd +Menu 0xdd + +# evdev 128 (0x80), QKeyCode "stop", number 0xe8 +Cancel 0xe8 + +# evdev 129 (0x81), QKeyCode "again", number 0x85 +Redo 0x85 + +# evdev 130 (0x82), QKeyCode "props", number 0x86 +SunProps 0x86 + +# evdev 131 (0x83), QKeyCode "undo", number 0x87 +Undo 0x87 + +# evdev 132 (0x84), QKeyCode "front", number 0x8c +SunFront 0x8c + +# evdev 133 (0x85), QKeyCode "copy", number 0xf8 +XF86Copy 0xf8 + +# evdev 134 (0x86), QKeyCode "open", number 0x64 +XF86Open 0x64 + +# evdev 135 (0x87), QKeyCode "paste", number 0x65 +XF86Paste 0x65 + +# evdev 136 (0x88), QKeyCode "find", number 0xc1 +Find 0xc1 + +# evdev 137 (0x89), QKeyCode "cut", number 0xbc +XF86Cut 0xbc + +# evdev 138 (0x8a), QKeyCode "help", number 0xf5 +Help 0xf5 + +# evdev 139 (0x8b), QKeyCode "menu", number 0x9e +XF86MenuKB 0x9e + +# evdev 140 (0x8c), QKeyCode "calculator", number 0xa1 +XF86Calculator 0xa1 + +# evdev 141 (0x8d): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 142 (0x8e), QKeyCode "sleep", number 0xdf +XF86Sleep 0xdf + +# evdev 143 (0x8f), QKeyCode "wake", number 0xe3 +XF86WakeUp 0xe3 + +# evdev 144 (0x90): no evdev -> QKeyCode mapping (xkb keysym XF86Explorer) + +# evdev 145 (0x91): no evdev -> QKeyCode mapping (xkb keysym XF86Send) + +# evdev 146 (0x92): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 147 (0x93): no evdev -> QKeyCode mapping (xkb keysym XF86Xfer) + +# evdev 148 (0x94): no evdev -> QKeyCode mapping (xkb keysym XF86Launch1) + +# evdev 149 (0x95): no evdev -> QKeyCode mapping (xkb keysym XF86Launch2) + +# evdev 150 (0x96): no evdev -> QKeyCode mapping (xkb keysym XF86WWW) + +# evdev 151 (0x97): no evdev -> QKeyCode mapping (xkb keysym XF86DOS) + +# evdev 152 (0x98): no evdev -> QKeyCode mapping (xkb keysym XF86ScreenSaver) + +# evdev 153 (0x99): no evdev -> QKeyCode mapping (xkb keysym XF86RotateWindows) + +# evdev 154 (0x9a): no evdev -> QKeyCode mapping (xkb keysym XF86TaskPane) + +# evdev 155 (0x9b), QKeyCode "mail", number 0xec +XF86Mail 0xec + +# evdev 156 (0x9c), QKeyCode "ac_bookmarks", number 0xe6 +XF86Favorites 0xe6 + +# evdev 157 (0x9d), QKeyCode "computer", number 0xeb +XF86MyComputer 0xeb + +# evdev 158 (0x9e), QKeyCode "ac_back", number 0xea +XF86Back 0xea + +# evdev 159 (0x9f), QKeyCode "ac_forward", number 0xe9 +XF86Forward 0xe9 + +# evdev 160 (0xa0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 161 (0xa1): no evdev -> QKeyCode mapping (xkb keysym XF86Eject) + +# evdev 162 (0xa2): no evdev -> QKeyCode mapping (xkb keysym XF86Eject) + +# evdev 163 (0xa3), QKeyCode "audionext", number 0x99 +XF86AudioNext 0x99 + +# evdev 164 (0xa4), QKeyCode "audioplay", number 0xa2 +XF86AudioPlay 0xa2 +XF86AudioPause 0xa2 shift + +# evdev 165 (0xa5), QKeyCode "audioprev", number 0x90 +XF86AudioPrev 0x90 + +# evdev 166 (0xa6), QKeyCode "audiostop", number 0xa4 +XF86AudioStop 0xa4 +XF86Eject 0xa4 shift + +# evdev 167 (0xa7): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRecord) + +# evdev 168 (0xa8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRewind) + +# evdev 169 (0xa9): no evdev -> QKeyCode mapping (xkb keysym XF86Phone) + +# evdev 170 (0xaa): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 171 (0xab): no evdev -> QKeyCode mapping (xkb keysym XF86Tools) + +# evdev 172 (0xac), QKeyCode "ac_home", number 0xb2 +XF86HomePage 0xb2 + +# evdev 173 (0xad), QKeyCode "ac_refresh", number 0xe7 +XF86Reload 0xe7 + +# evdev 174 (0xae): no evdev -> QKeyCode mapping (xkb keysym XF86Close) + +# evdev 175 (0xaf): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 176 (0xb0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 177 (0xb1): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollUp) + +# evdev 178 (0xb2): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollDown) + +# evdev 179 (0xb3): no evdev -> QKeyCode mapping (xkb keysym parenleft) + +# evdev 180 (0xb4): no evdev -> QKeyCode mapping (xkb keysym parenright) + +# evdev 181 (0xb5): no evdev -> QKeyCode mapping (xkb keysym XF86New) + +# evdev 182 (0xb6): no evdev -> QKeyCode mapping (xkb keysym Redo) + +# evdev 183 (0xb7): no evdev -> QKeyCode mapping (xkb keysym XF86Tools) + +# evdev 184 (0xb8): no evdev -> QKeyCode mapping (xkb keysym XF86Launch5) + +# evdev 185 (0xb9): no evdev -> QKeyCode mapping (xkb keysym XF86Launch6) + +# evdev 186 (0xba): no evdev -> QKeyCode mapping (xkb keysym XF86Launch7) + +# evdev 187 (0xbb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch8) + +# evdev 188 (0xbc): no evdev -> QKeyCode mapping (xkb keysym XF86Launch9) + +# evdev 189 (0xbd): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 190 (0xbe): no evdev -> QKeyCode mapping (xkb keysym XF86AudioMicMute) + +# evdev 191 (0xbf): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadToggle) + +# evdev 192 (0xc0): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOn) + +# evdev 193 (0xc1): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOff) + +# evdev 194 (0xc2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 195 (0xc3): no evdev -> QKeyCode mapping (xkb keysym Mode_switch) + +# evdev 196 (0xc4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 197 (0xc5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 198 (0xc6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 199 (0xc7): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 200 (0xc8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay) + +# evdev 201 (0xc9): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPause) + +# evdev 202 (0xca): no evdev -> QKeyCode mapping (xkb keysym XF86Launch3) + +# evdev 203 (0xcb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch4) + +# evdev 204 (0xcc): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchB) + +# evdev 205 (0xcd): no evdev -> QKeyCode mapping (xkb keysym XF86Suspend) + +# evdev 206 (0xce): no evdev -> QKeyCode mapping (xkb keysym XF86Close) + +# evdev 207 (0xcf): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay) + +# evdev 208 (0xd0): no evdev -> QKeyCode mapping (xkb keysym XF86AudioForward) + +# evdev 209 (0xd1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 210 (0xd2): no evdev -> QKeyCode mapping (xkb keysym Print) + +# evdev 211 (0xd3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 212 (0xd4): no evdev -> QKeyCode mapping (xkb keysym XF86WebCam) + +# evdev 213 (0xd5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 214 (0xd6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 215 (0xd7): no evdev -> QKeyCode mapping (xkb keysym XF86Mail) + +# evdev 216 (0xd8): no evdev -> QKeyCode mapping (xkb keysym XF86Messenger) + +# evdev 217 (0xd9): no evdev -> QKeyCode mapping (xkb keysym XF86Search) + +# evdev 218 (0xda): no evdev -> QKeyCode mapping (xkb keysym XF86Go) + +# evdev 219 (0xdb): no evdev -> QKeyCode mapping (xkb keysym XF86Finance) + +# evdev 220 (0xdc): no evdev -> QKeyCode mapping (xkb keysym XF86Game) + +# evdev 221 (0xdd): no evdev -> QKeyCode mapping (xkb keysym XF86Shop) + +# evdev 222 (0xde): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 223 (0xdf): no evdev -> QKeyCode mapping (xkb keysym Cancel) + +# evdev 224 (0xe0): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessDown) + +# evdev 225 (0xe1): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessUp) + +# evdev 226 (0xe2), QKeyCode "mediaselect", number 0xed +XF86AudioMedia 0xed + +# evdev 227 (0xe3): no evdev -> QKeyCode mapping (xkb keysym XF86Display) + +# evdev 228 (0xe4): no evdev -> QKeyCode mapping (xkb keysym XF86KbdLightOnOff) + +# evdev 229 (0xe5): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessDown) + +# evdev 230 (0xe6): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessUp) + +# evdev 231 (0xe7): no evdev -> QKeyCode mapping (xkb keysym XF86Send) + +# evdev 232 (0xe8): no evdev -> QKeyCode mapping (xkb keysym XF86Reply) + +# evdev 233 (0xe9): no evdev -> QKeyCode mapping (xkb keysym XF86MailForward) + +# evdev 234 (0xea): no evdev -> QKeyCode mapping (xkb keysym XF86Save) + +# evdev 235 (0xeb): no evdev -> QKeyCode mapping (xkb keysym XF86Documents) + +# evdev 236 (0xec): no evdev -> QKeyCode mapping (xkb keysym XF86Battery) + +# evdev 237 (0xed): no evdev -> QKeyCode mapping (xkb keysym XF86Bluetooth) + +# evdev 238 (0xee): no evdev -> QKeyCode mapping (xkb keysym XF86WLAN) + +# evdev 239 (0xef): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 240 (0xf0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 241 (0xf1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 242 (0xf2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 243 (0xf3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 244 (0xf4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 245 (0xf5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 246 (0xf6): no evdev -> QKeyCode mapping (xkb keysym 0x0a865600) + +# evdev 247 (0xf7): no evdev -> QKeyCode mapping (xkb keysym 0x0a865710) + +# +# quirks section start +# +# Sometimes multiple keysyms map to the same keycodes. +# The keycode -> keysym lookup finds only one of the +# keysyms. So append them here. +# + +Print 0x54 +Sys_Req 0x54 +Execute 0x54 +KP_Decimal 0x53 numlock +KP_Separator 0x53 numlock +Alt_R 0xb8 +ISO_Level3_Shift 0xb8 +Mode_switch 0xb8 + +# quirks section end diff --git a/app/src/main/assets/roms/keymaps/is b/app/src/main/assets/roms/keymaps/is new file mode 100644 index 0000000..c88fa60 --- /dev/null +++ b/app/src/main/assets/roms/keymaps/is @@ -0,0 +1,843 @@ +# +# generated by qemu-keymap +# model : pc105 +# layout : is +# variant : - +# options : - + +# name: "Icelandic" + +# modifiers +# 0: Shift +# 1: Lock +# 2: Control +# 3: Mod1 +# 4: Mod2 +# 5: Mod3 +# 6: Mod4 +# 7: Mod5 +# 8: NumLock +# 9: Alt +# 10: LevelThree +# 11: LAlt +# 12: RAlt +# 13: RControl +# 14: LControl +# 15: ScrollLock +# 16: LevelFive +# 17: AltGr +# 18: Meta +# 19: Super +# 20: Hyper + +# evdev 1 (0x1), QKeyCode "esc", number 0x1 +Escape 0x01 + +# evdev 2 (0x2), QKeyCode "1", number 0x2 +1 0x02 +exclam 0x02 shift +onesuperior 0x02 altgr +exclamdown 0x02 shift altgr + +# evdev 3 (0x3), QKeyCode "2", number 0x3 +2 0x03 +quotedbl 0x03 shift +twosuperior 0x03 altgr +oneeighth 0x03 shift altgr + +# evdev 4 (0x4), QKeyCode "3", number 0x4 +3 0x04 +numbersign 0x04 shift +threesuperior 0x04 altgr +sterling 0x04 shift altgr + +# evdev 5 (0x5), QKeyCode "4", number 0x5 +4 0x05 +dollar 0x05 shift +onequarter 0x05 altgr +currency 0x05 shift altgr + +# evdev 6 (0x6), QKeyCode "5", number 0x6 +5 0x06 +percent 0x06 shift +onehalf 0x06 altgr +threeeighths 0x06 shift altgr + +# evdev 7 (0x7), QKeyCode "6", number 0x7 +6 0x07 +ampersand 0x07 shift +notsign 0x07 altgr +fiveeighths 0x07 shift altgr + +# evdev 8 (0x8), QKeyCode "7", number 0x8 +7 0x08 +slash 0x08 shift +braceleft 0x08 altgr +seveneighths 0x08 shift altgr + +# evdev 9 (0x9), QKeyCode "8", number 0x9 +8 0x09 +parenleft 0x09 shift +bracketleft 0x09 altgr +trademark 0x09 shift altgr + +# evdev 10 (0xa), QKeyCode "9", number 0xa +9 0x0a +parenright 0x0a shift +bracketright 0x0a altgr +plusminus 0x0a shift altgr + +# evdev 11 (0xb), QKeyCode "0", number 0xb +0 0x0b +equal 0x0b shift +braceright 0x0b altgr +degree 0x0b shift altgr + +# evdev 12 (0xc), QKeyCode "minus", number 0xc +odiaeresis 0x0c +Odiaeresis 0x0c shift +backslash 0x0c altgr +questiondown 0x0c shift altgr + +# evdev 13 (0xd), QKeyCode "equal", number 0xd +minus 0x0d +underscore 0x0d shift +dead_cedilla 0x0d altgr +dead_ogonek 0x0d shift altgr + +# evdev 14 (0xe), QKeyCode "backspace", number 0xe +BackSpace 0x0e + +# evdev 15 (0xf), QKeyCode "tab", number 0xf +Tab 0x0f +ISO_Left_Tab 0x0f shift + +# evdev 16 (0x10), QKeyCode "q", number 0x10 +q 0x10 +Q 0x10 shift +at 0x10 altgr +Greek_OMEGA 0x10 shift altgr + +# evdev 17 (0x11), QKeyCode "w", number 0x11 +w 0x11 +W 0x11 shift +lstroke 0x11 altgr +Lstroke 0x11 shift altgr + +# evdev 18 (0x12), QKeyCode "e", number 0x12 +e 0x12 +E 0x12 shift +EuroSign 0x12 altgr +cent 0x12 shift altgr + +# evdev 19 (0x13), QKeyCode "r", number 0x13 +r 0x13 +R 0x13 shift +paragraph 0x13 altgr +registered 0x13 shift altgr + +# evdev 20 (0x14), QKeyCode "t", number 0x14 +t 0x14 +T 0x14 shift +tslash 0x14 altgr +Tslash 0x14 shift altgr + +# evdev 21 (0x15), QKeyCode "y", number 0x15 +y 0x15 +Y 0x15 shift +leftarrow 0x15 altgr +yen 0x15 shift altgr + +# evdev 22 (0x16), QKeyCode "u", number 0x16 +u 0x16 +U 0x16 shift +downarrow 0x16 altgr +uparrow 0x16 shift altgr + +# evdev 23 (0x17), QKeyCode "i", number 0x17 +i 0x17 +I 0x17 shift +rightarrow 0x17 altgr +idotless 0x17 shift altgr + +# evdev 24 (0x18), QKeyCode "o", number 0x18 +o 0x18 +O 0x18 shift +oslash 0x18 altgr +Oslash 0x18 shift altgr + +# evdev 25 (0x19), QKeyCode "p", number 0x19 +p 0x19 +P 0x19 shift +thorn 0x19 altgr +THORN 0x19 shift altgr + +# evdev 26 (0x1a), QKeyCode "bracket_left", number 0x1a +eth 0x1a +ETH 0x1a shift +dead_diaeresis 0x1a altgr +dead_abovering 0x1a shift altgr + +# evdev 27 (0x1b), QKeyCode "bracket_right", number 0x1b +apostrophe 0x1b +question 0x1b shift +asciitilde 0x1b altgr +dead_macron 0x1b shift altgr + +# evdev 28 (0x1c), QKeyCode "ret", number 0x1c +Return 0x1c + +# evdev 29 (0x1d), QKeyCode "ctrl", number 0x1d +Control_L 0x1d + +# evdev 30 (0x1e), QKeyCode "a", number 0x1e +a 0x1e +A 0x1e shift +ae 0x1e altgr +AE 0x1e shift altgr + +# evdev 31 (0x1f), QKeyCode "s", number 0x1f +s 0x1f +S 0x1f shift +ssharp 0x1f altgr +section 0x1f shift altgr + +# evdev 32 (0x20), QKeyCode "d", number 0x20 +d 0x20 +D 0x20 shift +U201E 0x20 altgr +U201C 0x20 shift altgr + +# evdev 33 (0x21), QKeyCode "f", number 0x21 +f 0x21 +F 0x21 shift +dstroke 0x21 altgr +ordfeminine 0x21 shift altgr + +# evdev 34 (0x22), QKeyCode "g", number 0x22 +g 0x22 +G 0x22 shift +eng 0x22 altgr +ENG 0x22 shift altgr + +# evdev 35 (0x23), QKeyCode "h", number 0x23 +h 0x23 +H 0x23 shift +hstroke 0x23 altgr +Hstroke 0x23 shift altgr + +# evdev 36 (0x24), QKeyCode "j", number 0x24 +j 0x24 +J 0x24 shift +dead_hook 0x24 altgr +dead_horn 0x24 shift altgr + +# evdev 37 (0x25), QKeyCode "k", number 0x25 +k 0x25 +K 0x25 shift +kra 0x25 altgr +ampersand 0x25 shift altgr + +# evdev 38 (0x26), QKeyCode "l", number 0x26 +l 0x26 +L 0x26 shift +lstroke 0x26 altgr +Lstroke 0x26 shift altgr + +# evdev 39 (0x27), QKeyCode "semicolon", number 0x27 +ae 0x27 +AE 0x27 shift +asciicircum 0x27 altgr +dead_doubleacute 0x27 shift altgr + +# evdev 40 (0x28), QKeyCode "apostrophe", number 0x28 +dead_acute 0x28 +dead_circumflex 0x28 altgr +dead_caron 0x28 shift altgr + +# evdev 41 (0x29), QKeyCode "grave_accent", number 0x29 +dead_abovering 0x29 +dead_diaeresis 0x29 shift +notsign 0x29 altgr +hyphen 0x29 shift altgr + +# evdev 42 (0x2a), QKeyCode "shift", number 0x2a +Shift_L 0x2a + +# evdev 43 (0x2b), QKeyCode "backslash", number 0x2b +plus 0x2b +asterisk 0x2b shift +grave 0x2b altgr +dead_breve 0x2b shift altgr + +# evdev 44 (0x2c), QKeyCode "z", number 0x2c +z 0x2c +Z 0x2c shift +guillemotleft 0x2c altgr +less 0x2c shift altgr + +# evdev 45 (0x2d), QKeyCode "x", number 0x2d +x 0x2d +X 0x2d shift +guillemotright 0x2d altgr +greater 0x2d shift altgr + +# evdev 46 (0x2e), QKeyCode "c", number 0x2e +c 0x2e +C 0x2e shift +cent 0x2e altgr +copyright 0x2e shift altgr + +# evdev 47 (0x2f), QKeyCode "v", number 0x2f +v 0x2f +V 0x2f shift +leftdoublequotemark 0x2f altgr +leftsinglequotemark 0x2f shift altgr + +# evdev 48 (0x30), QKeyCode "b", number 0x30 +b 0x30 +B 0x30 shift +rightdoublequotemark 0x30 altgr +rightsinglequotemark 0x30 shift altgr + +# evdev 49 (0x31), QKeyCode "n", number 0x31 +n 0x31 +N 0x31 shift + +# evdev 50 (0x32), QKeyCode "m", number 0x32 +m 0x32 +M 0x32 shift +mu 0x32 altgr +masculine 0x32 shift altgr + +# evdev 51 (0x33), QKeyCode "comma", number 0x33 +comma 0x33 +semicolon 0x33 shift +horizconnector 0x33 altgr +multiply 0x33 shift altgr + +# evdev 52 (0x34), QKeyCode "dot", number 0x34 +period 0x34 +colon 0x34 shift +periodcentered 0x34 altgr +division 0x34 shift altgr + +# evdev 53 (0x35), QKeyCode "slash", number 0x35 +thorn 0x35 +THORN 0x35 shift +dead_belowdot 0x35 altgr +dead_abovedot 0x35 shift altgr + +# evdev 54 (0x36), QKeyCode "shift_r", number 0x36 +Shift_R 0x36 + +# evdev 55 (0x37), QKeyCode "kp_multiply", number 0x37 +KP_Multiply 0x37 + +# evdev 56 (0x38), QKeyCode "alt", number 0x38 +Alt_L 0x38 +Meta_L 0x38 shift + +# evdev 57 (0x39), QKeyCode "spc", number 0x39 +space 0x39 + +# evdev 58 (0x3a), QKeyCode "caps_lock", number 0x3a +Caps_Lock 0x3a + +# evdev 59 (0x3b), QKeyCode "f1", number 0x3b +F1 0x3b + +# evdev 60 (0x3c), QKeyCode "f2", number 0x3c +F2 0x3c + +# evdev 61 (0x3d), QKeyCode "f3", number 0x3d +F3 0x3d + +# evdev 62 (0x3e), QKeyCode "f4", number 0x3e +F4 0x3e + +# evdev 63 (0x3f), QKeyCode "f5", number 0x3f +F5 0x3f + +# evdev 64 (0x40), QKeyCode "f6", number 0x40 +F6 0x40 + +# evdev 65 (0x41), QKeyCode "f7", number 0x41 +F7 0x41 + +# evdev 66 (0x42), QKeyCode "f8", number 0x42 +F8 0x42 + +# evdev 67 (0x43), QKeyCode "f9", number 0x43 +F9 0x43 + +# evdev 68 (0x44), QKeyCode "f10", number 0x44 +F10 0x44 + +# evdev 69 (0x45), QKeyCode "num_lock", number 0x45 +Num_Lock 0x45 + +# evdev 70 (0x46), QKeyCode "scroll_lock", number 0x46 +Scroll_Lock 0x46 + +# evdev 71 (0x47), QKeyCode "kp_7", number 0x47 +KP_Home 0x47 +KP_7 0x47 numlock + +# evdev 72 (0x48), QKeyCode "kp_8", number 0x48 +KP_Up 0x48 +KP_8 0x48 numlock + +# evdev 73 (0x49), QKeyCode "kp_9", number 0x49 +KP_Prior 0x49 +KP_9 0x49 numlock + +# evdev 74 (0x4a), QKeyCode "kp_subtract", number 0x4a +KP_Subtract 0x4a + +# evdev 75 (0x4b), QKeyCode "kp_4", number 0x4b +KP_Left 0x4b +KP_4 0x4b numlock + +# evdev 76 (0x4c), QKeyCode "kp_5", number 0x4c +KP_Begin 0x4c +KP_5 0x4c numlock + +# evdev 77 (0x4d), QKeyCode "kp_6", number 0x4d +KP_Right 0x4d +KP_6 0x4d numlock + +# evdev 78 (0x4e), QKeyCode "kp_add", number 0x4e +KP_Add 0x4e + +# evdev 79 (0x4f), QKeyCode "kp_1", number 0x4f +KP_End 0x4f +KP_1 0x4f numlock + +# evdev 80 (0x50), QKeyCode "kp_2", number 0x50 +KP_Down 0x50 +KP_2 0x50 numlock + +# evdev 81 (0x51), QKeyCode "kp_3", number 0x51 +KP_Next 0x51 +KP_3 0x51 numlock + +# evdev 82 (0x52), QKeyCode "kp_0", number 0x52 +KP_Insert 0x52 +KP_0 0x52 numlock + +# evdev 83 (0x53), QKeyCode "kp_decimal", number 0x53 +KP_Delete 0x53 +KP_Decimal 0x53 numlock + +# evdev 84 (0x54): no evdev -> QKeyCode mapping (xkb keysym ISO_Level3_Shift) + +# evdev 85 (0x55): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 86 (0x56), QKeyCode "less", number 0x56 +less 0x56 +greater 0x56 shift +bar 0x56 altgr +brokenbar 0x56 shift altgr + +# evdev 87 (0x57), QKeyCode "f11", number 0x57 +F11 0x57 + +# evdev 88 (0x58), QKeyCode "f12", number 0x58 +F12 0x58 + +# evdev 89 (0x59), QKeyCode "ro", number 0x73 + +# evdev 90 (0x5a): no evdev -> QKeyCode mapping (xkb keysym Katakana) + +# evdev 91 (0x5b), QKeyCode "hiragana", number 0x77 +Hiragana 0x77 + +# evdev 92 (0x5c), QKeyCode "henkan", number 0x79 +Henkan_Mode 0x79 + +# evdev 93 (0x5d), QKeyCode "katakanahiragana", number 0x70 +Hiragana_Katakana 0x70 + +# evdev 94 (0x5e), QKeyCode "muhenkan", number 0x7b +Muhenkan 0x7b + +# evdev 95 (0x5f): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 96 (0x60), QKeyCode "kp_enter", number 0x9c +KP_Enter 0x9c + +# evdev 97 (0x61), QKeyCode "ctrl_r", number 0x9d +Control_R 0x9d + +# evdev 98 (0x62), QKeyCode "kp_divide", number 0xb5 +KP_Divide 0xb5 + +# evdev 99 (0x63), QKeyCode "sysrq", number 0x54 +Print 0x54 + +# evdev 100 (0x64), QKeyCode "alt_r", number 0xb8 +ISO_Level3_Shift 0xb8 + +# evdev 101 (0x65), QKeyCode "lf", number 0x5b +Linefeed 0x5b + +# evdev 102 (0x66), QKeyCode "home", number 0xc7 +Home 0xc7 + +# evdev 103 (0x67), QKeyCode "up", number 0xc8 +Up 0xc8 + +# evdev 104 (0x68), QKeyCode "pgup", number 0xc9 +Prior 0xc9 + +# evdev 105 (0x69), QKeyCode "left", number 0xcb +Left 0xcb + +# evdev 106 (0x6a), QKeyCode "right", number 0xcd +Right 0xcd + +# evdev 107 (0x6b), QKeyCode "end", number 0xcf +End 0xcf + +# evdev 108 (0x6c), QKeyCode "down", number 0xd0 +Down 0xd0 + +# evdev 109 (0x6d), QKeyCode "pgdn", number 0xd1 +Next 0xd1 + +# evdev 110 (0x6e), QKeyCode "insert", number 0xd2 +Insert 0xd2 + +# evdev 111 (0x6f), QKeyCode "delete", number 0xd3 +Delete 0xd3 + +# evdev 112 (0x70): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 113 (0x71), QKeyCode "audiomute", number 0xa0 +XF86AudioMute 0xa0 + +# evdev 114 (0x72), QKeyCode "volumedown", number 0xae +XF86AudioLowerVolume 0xae + +# evdev 115 (0x73), QKeyCode "volumeup", number 0xb0 +XF86AudioRaiseVolume 0xb0 + +# evdev 116 (0x74), QKeyCode "power", number 0xde +XF86PowerOff 0xde + +# evdev 117 (0x75), QKeyCode "kp_equals", number 0x59 +KP_Equal 0x59 + +# evdev 118 (0x76): no evdev -> QKeyCode mapping (xkb keysym plusminus) + +# evdev 119 (0x77), QKeyCode "pause", number 0xc6 +Pause 0xc6 + +# evdev 120 (0x78): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchA) + +# evdev 121 (0x79), QKeyCode "kp_comma", number 0x7e +KP_Decimal 0x7e + +# evdev 122 (0x7a): no evdev -> QKeyCode mapping (xkb keysym Hangul) + +# evdev 123 (0x7b): no evdev -> QKeyCode mapping (xkb keysym Hangul_Hanja) + +# evdev 124 (0x7c), QKeyCode "yen", number 0x7d + +# evdev 125 (0x7d), QKeyCode "meta_l", number 0xdb +Super_L 0xdb + +# evdev 126 (0x7e), QKeyCode "meta_r", number 0xdc +Super_R 0xdc + +# evdev 127 (0x7f), QKeyCode "compose", number 0xdd +Menu 0xdd + +# evdev 128 (0x80), QKeyCode "stop", number 0xe8 +Cancel 0xe8 + +# evdev 129 (0x81), QKeyCode "again", number 0x85 +Redo 0x85 + +# evdev 130 (0x82), QKeyCode "props", number 0x86 +SunProps 0x86 + +# evdev 131 (0x83), QKeyCode "undo", number 0x87 +Undo 0x87 + +# evdev 132 (0x84), QKeyCode "front", number 0x8c +SunFront 0x8c + +# evdev 133 (0x85), QKeyCode "copy", number 0xf8 +XF86Copy 0xf8 + +# evdev 134 (0x86), QKeyCode "open", number 0x64 +XF86Open 0x64 + +# evdev 135 (0x87), QKeyCode "paste", number 0x65 +XF86Paste 0x65 + +# evdev 136 (0x88), QKeyCode "find", number 0xc1 +Find 0xc1 + +# evdev 137 (0x89), QKeyCode "cut", number 0xbc +XF86Cut 0xbc + +# evdev 138 (0x8a), QKeyCode "help", number 0xf5 +Help 0xf5 + +# evdev 139 (0x8b), QKeyCode "menu", number 0x9e +XF86MenuKB 0x9e + +# evdev 140 (0x8c), QKeyCode "calculator", number 0xa1 +XF86Calculator 0xa1 + +# evdev 141 (0x8d): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 142 (0x8e), QKeyCode "sleep", number 0xdf +XF86Sleep 0xdf + +# evdev 143 (0x8f), QKeyCode "wake", number 0xe3 +XF86WakeUp 0xe3 + +# evdev 144 (0x90): no evdev -> QKeyCode mapping (xkb keysym XF86Explorer) + +# evdev 145 (0x91): no evdev -> QKeyCode mapping (xkb keysym XF86Send) + +# evdev 146 (0x92): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 147 (0x93): no evdev -> QKeyCode mapping (xkb keysym XF86Xfer) + +# evdev 148 (0x94): no evdev -> QKeyCode mapping (xkb keysym XF86Launch1) + +# evdev 149 (0x95): no evdev -> QKeyCode mapping (xkb keysym XF86Launch2) + +# evdev 150 (0x96): no evdev -> QKeyCode mapping (xkb keysym XF86WWW) + +# evdev 151 (0x97): no evdev -> QKeyCode mapping (xkb keysym XF86DOS) + +# evdev 152 (0x98): no evdev -> QKeyCode mapping (xkb keysym XF86ScreenSaver) + +# evdev 153 (0x99): no evdev -> QKeyCode mapping (xkb keysym XF86RotateWindows) + +# evdev 154 (0x9a): no evdev -> QKeyCode mapping (xkb keysym XF86TaskPane) + +# evdev 155 (0x9b), QKeyCode "mail", number 0xec +XF86Mail 0xec + +# evdev 156 (0x9c), QKeyCode "ac_bookmarks", number 0xe6 +XF86Favorites 0xe6 + +# evdev 157 (0x9d), QKeyCode "computer", number 0xeb +XF86MyComputer 0xeb + +# evdev 158 (0x9e), QKeyCode "ac_back", number 0xea +XF86Back 0xea + +# evdev 159 (0x9f), QKeyCode "ac_forward", number 0xe9 +XF86Forward 0xe9 + +# evdev 160 (0xa0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 161 (0xa1): no evdev -> QKeyCode mapping (xkb keysym XF86Eject) + +# evdev 162 (0xa2): no evdev -> QKeyCode mapping (xkb keysym XF86Eject) + +# evdev 163 (0xa3), QKeyCode "audionext", number 0x99 +XF86AudioNext 0x99 + +# evdev 164 (0xa4), QKeyCode "audioplay", number 0xa2 +XF86AudioPlay 0xa2 +XF86AudioPause 0xa2 shift + +# evdev 165 (0xa5), QKeyCode "audioprev", number 0x90 +XF86AudioPrev 0x90 + +# evdev 166 (0xa6), QKeyCode "audiostop", number 0xa4 +XF86AudioStop 0xa4 +XF86Eject 0xa4 shift + +# evdev 167 (0xa7): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRecord) + +# evdev 168 (0xa8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRewind) + +# evdev 169 (0xa9): no evdev -> QKeyCode mapping (xkb keysym XF86Phone) + +# evdev 170 (0xaa): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 171 (0xab): no evdev -> QKeyCode mapping (xkb keysym XF86Tools) + +# evdev 172 (0xac), QKeyCode "ac_home", number 0xb2 +XF86HomePage 0xb2 + +# evdev 173 (0xad), QKeyCode "ac_refresh", number 0xe7 +XF86Reload 0xe7 + +# evdev 174 (0xae): no evdev -> QKeyCode mapping (xkb keysym XF86Close) + +# evdev 175 (0xaf): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 176 (0xb0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 177 (0xb1): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollUp) + +# evdev 178 (0xb2): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollDown) + +# evdev 179 (0xb3): no evdev -> QKeyCode mapping (xkb keysym parenleft) + +# evdev 180 (0xb4): no evdev -> QKeyCode mapping (xkb keysym parenright) + +# evdev 181 (0xb5): no evdev -> QKeyCode mapping (xkb keysym XF86New) + +# evdev 182 (0xb6): no evdev -> QKeyCode mapping (xkb keysym Redo) + +# evdev 183 (0xb7): no evdev -> QKeyCode mapping (xkb keysym XF86Tools) + +# evdev 184 (0xb8): no evdev -> QKeyCode mapping (xkb keysym XF86Launch5) + +# evdev 185 (0xb9): no evdev -> QKeyCode mapping (xkb keysym XF86Launch6) + +# evdev 186 (0xba): no evdev -> QKeyCode mapping (xkb keysym XF86Launch7) + +# evdev 187 (0xbb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch8) + +# evdev 188 (0xbc): no evdev -> QKeyCode mapping (xkb keysym XF86Launch9) + +# evdev 189 (0xbd): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 190 (0xbe): no evdev -> QKeyCode mapping (xkb keysym XF86AudioMicMute) + +# evdev 191 (0xbf): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadToggle) + +# evdev 192 (0xc0): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOn) + +# evdev 193 (0xc1): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOff) + +# evdev 194 (0xc2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 195 (0xc3): no evdev -> QKeyCode mapping (xkb keysym Mode_switch) + +# evdev 196 (0xc4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 197 (0xc5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 198 (0xc6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 199 (0xc7): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 200 (0xc8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay) + +# evdev 201 (0xc9): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPause) + +# evdev 202 (0xca): no evdev -> QKeyCode mapping (xkb keysym XF86Launch3) + +# evdev 203 (0xcb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch4) + +# evdev 204 (0xcc): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchB) + +# evdev 205 (0xcd): no evdev -> QKeyCode mapping (xkb keysym XF86Suspend) + +# evdev 206 (0xce): no evdev -> QKeyCode mapping (xkb keysym XF86Close) + +# evdev 207 (0xcf): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay) + +# evdev 208 (0xd0): no evdev -> QKeyCode mapping (xkb keysym XF86AudioForward) + +# evdev 209 (0xd1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 210 (0xd2): no evdev -> QKeyCode mapping (xkb keysym Print) + +# evdev 211 (0xd3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 212 (0xd4): no evdev -> QKeyCode mapping (xkb keysym XF86WebCam) + +# evdev 213 (0xd5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 214 (0xd6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 215 (0xd7): no evdev -> QKeyCode mapping (xkb keysym XF86Mail) + +# evdev 216 (0xd8): no evdev -> QKeyCode mapping (xkb keysym XF86Messenger) + +# evdev 217 (0xd9): no evdev -> QKeyCode mapping (xkb keysym XF86Search) + +# evdev 218 (0xda): no evdev -> QKeyCode mapping (xkb keysym XF86Go) + +# evdev 219 (0xdb): no evdev -> QKeyCode mapping (xkb keysym XF86Finance) + +# evdev 220 (0xdc): no evdev -> QKeyCode mapping (xkb keysym XF86Game) + +# evdev 221 (0xdd): no evdev -> QKeyCode mapping (xkb keysym XF86Shop) + +# evdev 222 (0xde): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 223 (0xdf): no evdev -> QKeyCode mapping (xkb keysym Cancel) + +# evdev 224 (0xe0): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessDown) + +# evdev 225 (0xe1): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessUp) + +# evdev 226 (0xe2), QKeyCode "mediaselect", number 0xed +XF86AudioMedia 0xed + +# evdev 227 (0xe3): no evdev -> QKeyCode mapping (xkb keysym XF86Display) + +# evdev 228 (0xe4): no evdev -> QKeyCode mapping (xkb keysym XF86KbdLightOnOff) + +# evdev 229 (0xe5): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessDown) + +# evdev 230 (0xe6): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessUp) + +# evdev 231 (0xe7): no evdev -> QKeyCode mapping (xkb keysym XF86Send) + +# evdev 232 (0xe8): no evdev -> QKeyCode mapping (xkb keysym XF86Reply) + +# evdev 233 (0xe9): no evdev -> QKeyCode mapping (xkb keysym XF86MailForward) + +# evdev 234 (0xea): no evdev -> QKeyCode mapping (xkb keysym XF86Save) + +# evdev 235 (0xeb): no evdev -> QKeyCode mapping (xkb keysym XF86Documents) + +# evdev 236 (0xec): no evdev -> QKeyCode mapping (xkb keysym XF86Battery) + +# evdev 237 (0xed): no evdev -> QKeyCode mapping (xkb keysym XF86Bluetooth) + +# evdev 238 (0xee): no evdev -> QKeyCode mapping (xkb keysym XF86WLAN) + +# evdev 239 (0xef): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 240 (0xf0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 241 (0xf1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 242 (0xf2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 243 (0xf3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 244 (0xf4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 245 (0xf5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 246 (0xf6): no evdev -> QKeyCode mapping (xkb keysym Invalid) + +# evdev 247 (0xf7): no evdev -> QKeyCode mapping (xkb keysym Invalid) + +# +# quirks section start +# +# Sometimes multiple keysyms map to the same keycodes. +# The keycode -> keysym lookup finds only one of the +# keysyms. So append them here. +# + +Print 0x54 +Sys_Req 0x54 +Execute 0x54 +KP_Decimal 0x53 numlock +KP_Separator 0x53 numlock +Alt_R 0xb8 +ISO_Level3_Shift 0xb8 +Mode_switch 0xb8 + +# quirks section end diff --git a/app/src/main/assets/roms/keymaps/it b/app/src/main/assets/roms/keymaps/it new file mode 100644 index 0000000..df00156 --- /dev/null +++ b/app/src/main/assets/roms/keymaps/it @@ -0,0 +1,846 @@ +# +# generated by qemu-keymap +# model : pc105 +# layout : it +# variant : - +# options : - + +# name: "Italian" + +# modifiers +# 0: Shift +# 1: Lock +# 2: Control +# 3: Mod1 +# 4: Mod2 +# 5: Mod3 +# 6: Mod4 +# 7: Mod5 +# 8: NumLock +# 9: Alt +# 10: LevelThree +# 11: LAlt +# 12: RAlt +# 13: RControl +# 14: LControl +# 15: ScrollLock +# 16: LevelFive +# 17: AltGr +# 18: Meta +# 19: Super +# 20: Hyper + +# evdev 1 (0x1), QKeyCode "esc", number 0x1 +Escape 0x01 + +# evdev 2 (0x2), QKeyCode "1", number 0x2 +1 0x02 +exclam 0x02 shift +onesuperior 0x02 altgr +exclamdown 0x02 shift altgr + +# evdev 3 (0x3), QKeyCode "2", number 0x3 +2 0x03 +quotedbl 0x03 shift +twosuperior 0x03 altgr +dead_doubleacute 0x03 shift altgr + +# evdev 4 (0x4), QKeyCode "3", number 0x4 +3 0x04 +sterling 0x04 shift +threesuperior 0x04 altgr +dead_tilde 0x04 shift altgr + +# evdev 5 (0x5), QKeyCode "4", number 0x5 +4 0x05 +dollar 0x05 shift +onequarter 0x05 altgr +oneeighth 0x05 shift altgr + +# evdev 6 (0x6), QKeyCode "5", number 0x6 +5 0x06 +percent 0x06 shift +onehalf 0x06 altgr +threeeighths 0x06 shift altgr + +# evdev 7 (0x7), QKeyCode "6", number 0x7 +6 0x07 +ampersand 0x07 shift +notsign 0x07 altgr +fiveeighths 0x07 shift altgr + +# evdev 8 (0x8), QKeyCode "7", number 0x8 +7 0x08 +slash 0x08 shift +braceleft 0x08 altgr +seveneighths 0x08 shift altgr + +# evdev 9 (0x9), QKeyCode "8", number 0x9 +8 0x09 +parenleft 0x09 shift +bracketleft 0x09 altgr +trademark 0x09 shift altgr + +# evdev 10 (0xa), QKeyCode "9", number 0xa +9 0x0a +parenright 0x0a shift +bracketright 0x0a altgr +plusminus 0x0a shift altgr + +# evdev 11 (0xb), QKeyCode "0", number 0xb +0 0x0b +equal 0x0b shift +braceright 0x0b altgr +dead_ogonek 0x0b shift altgr + +# evdev 12 (0xc), QKeyCode "minus", number 0xc +apostrophe 0x0c +question 0x0c shift +grave 0x0c altgr +questiondown 0x0c shift altgr + +# evdev 13 (0xd), QKeyCode "equal", number 0xd +igrave 0x0d +asciicircum 0x0d shift +asciitilde 0x0d altgr +dead_circumflex 0x0d shift altgr + +# evdev 14 (0xe), QKeyCode "backspace", number 0xe +BackSpace 0x0e + +# evdev 15 (0xf), QKeyCode "tab", number 0xf +Tab 0x0f +ISO_Left_Tab 0x0f shift + +# evdev 16 (0x10), QKeyCode "q", number 0x10 +q 0x10 +Q 0x10 shift +at 0x10 altgr +Greek_OMEGA 0x10 shift altgr + +# evdev 17 (0x11), QKeyCode "w", number 0x11 +w 0x11 +W 0x11 shift +lstroke 0x11 altgr +Lstroke 0x11 shift altgr + +# evdev 18 (0x12), QKeyCode "e", number 0x12 +e 0x12 +E 0x12 shift +EuroSign 0x12 altgr +cent 0x12 shift altgr + +# evdev 19 (0x13), QKeyCode "r", number 0x13 +r 0x13 +R 0x13 shift +paragraph 0x13 altgr +registered 0x13 shift altgr + +# evdev 20 (0x14), QKeyCode "t", number 0x14 +t 0x14 +T 0x14 shift +tslash 0x14 altgr +Tslash 0x14 shift altgr + +# evdev 21 (0x15), QKeyCode "y", number 0x15 +y 0x15 +Y 0x15 shift +leftarrow 0x15 altgr +yen 0x15 shift altgr + +# evdev 22 (0x16), QKeyCode "u", number 0x16 +u 0x16 +U 0x16 shift +downarrow 0x16 altgr +uparrow 0x16 shift altgr + +# evdev 23 (0x17), QKeyCode "i", number 0x17 +i 0x17 +I 0x17 shift +rightarrow 0x17 altgr +idotless 0x17 shift altgr + +# evdev 24 (0x18), QKeyCode "o", number 0x18 +o 0x18 +O 0x18 shift +oslash 0x18 altgr +Oslash 0x18 shift altgr + +# evdev 25 (0x19), QKeyCode "p", number 0x19 +p 0x19 +P 0x19 shift +thorn 0x19 altgr +THORN 0x19 shift altgr + +# evdev 26 (0x1a), QKeyCode "bracket_left", number 0x1a +egrave 0x1a +eacute 0x1a shift +bracketleft 0x1a altgr +braceleft 0x1a shift altgr + +# evdev 27 (0x1b), QKeyCode "bracket_right", number 0x1b +plus 0x1b +asterisk 0x1b shift +bracketright 0x1b altgr +braceright 0x1b shift altgr + +# evdev 28 (0x1c), QKeyCode "ret", number 0x1c +Return 0x1c + +# evdev 29 (0x1d), QKeyCode "ctrl", number 0x1d +Control_L 0x1d + +# evdev 30 (0x1e), QKeyCode "a", number 0x1e +a 0x1e +A 0x1e shift +ae 0x1e altgr +AE 0x1e shift altgr + +# evdev 31 (0x1f), QKeyCode "s", number 0x1f +s 0x1f +S 0x1f shift +ssharp 0x1f altgr +section 0x1f shift altgr + +# evdev 32 (0x20), QKeyCode "d", number 0x20 +d 0x20 +D 0x20 shift +eth 0x20 altgr +ETH 0x20 shift altgr + +# evdev 33 (0x21), QKeyCode "f", number 0x21 +f 0x21 +F 0x21 shift +dstroke 0x21 altgr +ordfeminine 0x21 shift altgr + +# evdev 34 (0x22), QKeyCode "g", number 0x22 +g 0x22 +G 0x22 shift +eng 0x22 altgr +ENG 0x22 shift altgr + +# evdev 35 (0x23), QKeyCode "h", number 0x23 +h 0x23 +H 0x23 shift +hstroke 0x23 altgr +Hstroke 0x23 shift altgr + +# evdev 36 (0x24), QKeyCode "j", number 0x24 +j 0x24 +J 0x24 shift +dead_hook 0x24 altgr +dead_horn 0x24 shift altgr + +# evdev 37 (0x25), QKeyCode "k", number 0x25 +k 0x25 +K 0x25 shift +kra 0x25 altgr +ampersand 0x25 shift altgr + +# evdev 38 (0x26), QKeyCode "l", number 0x26 +l 0x26 +L 0x26 shift +lstroke 0x26 altgr +Lstroke 0x26 shift altgr + +# evdev 39 (0x27), QKeyCode "semicolon", number 0x27 +ograve 0x27 +ccedilla 0x27 shift +at 0x27 altgr +dead_cedilla 0x27 shift altgr + +# evdev 40 (0x28), QKeyCode "apostrophe", number 0x28 +agrave 0x28 +degree 0x28 shift +numbersign 0x28 altgr +dead_abovering 0x28 shift altgr + +# evdev 41 (0x29), QKeyCode "grave_accent", number 0x29 +backslash 0x29 +bar 0x29 shift +notsign 0x29 altgr +brokenbar 0x29 shift altgr + +# evdev 42 (0x2a), QKeyCode "shift", number 0x2a +Shift_L 0x2a + +# evdev 43 (0x2b), QKeyCode "backslash", number 0x2b +ugrave 0x2b +section 0x2b shift +dead_grave 0x2b altgr +dead_breve 0x2b shift altgr + +# evdev 44 (0x2c), QKeyCode "z", number 0x2c +z 0x2c +Z 0x2c shift +guillemotleft 0x2c altgr +less 0x2c shift altgr + +# evdev 45 (0x2d), QKeyCode "x", number 0x2d +x 0x2d +X 0x2d shift +guillemotright 0x2d altgr +greater 0x2d shift altgr + +# evdev 46 (0x2e), QKeyCode "c", number 0x2e +c 0x2e +C 0x2e shift +cent 0x2e altgr +copyright 0x2e shift altgr + +# evdev 47 (0x2f), QKeyCode "v", number 0x2f +v 0x2f +V 0x2f shift +leftdoublequotemark 0x2f altgr +leftsinglequotemark 0x2f shift altgr + +# evdev 48 (0x30), QKeyCode "b", number 0x30 +b 0x30 +B 0x30 shift +rightdoublequotemark 0x30 altgr +rightsinglequotemark 0x30 shift altgr + +# evdev 49 (0x31), QKeyCode "n", number 0x31 +n 0x31 +N 0x31 shift +ntilde 0x31 altgr +Ntilde 0x31 shift altgr + +# evdev 50 (0x32), QKeyCode "m", number 0x32 +m 0x32 +M 0x32 shift +mu 0x32 altgr +masculine 0x32 shift altgr + +# evdev 51 (0x33), QKeyCode "comma", number 0x33 +comma 0x33 +semicolon 0x33 shift +dead_acute 0x33 altgr +multiply 0x33 shift altgr + +# evdev 52 (0x34), QKeyCode "dot", number 0x34 +period 0x34 +colon 0x34 shift +periodcentered 0x34 altgr +dead_diaeresis 0x34 shift altgr + +# evdev 53 (0x35), QKeyCode "slash", number 0x35 +minus 0x35 +underscore 0x35 shift +dead_macron 0x35 altgr +division 0x35 shift altgr + +# evdev 54 (0x36), QKeyCode "shift_r", number 0x36 +Shift_R 0x36 + +# evdev 55 (0x37), QKeyCode "kp_multiply", number 0x37 +KP_Multiply 0x37 + +# evdev 56 (0x38), QKeyCode "alt", number 0x38 +Alt_L 0x38 +Meta_L 0x38 shift + +# evdev 57 (0x39), QKeyCode "spc", number 0x39 +space 0x39 + +# evdev 58 (0x3a), QKeyCode "caps_lock", number 0x3a +Caps_Lock 0x3a + +# evdev 59 (0x3b), QKeyCode "f1", number 0x3b +F1 0x3b + +# evdev 60 (0x3c), QKeyCode "f2", number 0x3c +F2 0x3c + +# evdev 61 (0x3d), QKeyCode "f3", number 0x3d +F3 0x3d + +# evdev 62 (0x3e), QKeyCode "f4", number 0x3e +F4 0x3e + +# evdev 63 (0x3f), QKeyCode "f5", number 0x3f +F5 0x3f + +# evdev 64 (0x40), QKeyCode "f6", number 0x40 +F6 0x40 + +# evdev 65 (0x41), QKeyCode "f7", number 0x41 +F7 0x41 + +# evdev 66 (0x42), QKeyCode "f8", number 0x42 +F8 0x42 + +# evdev 67 (0x43), QKeyCode "f9", number 0x43 +F9 0x43 + +# evdev 68 (0x44), QKeyCode "f10", number 0x44 +F10 0x44 + +# evdev 69 (0x45), QKeyCode "num_lock", number 0x45 +Num_Lock 0x45 + +# evdev 70 (0x46), QKeyCode "scroll_lock", number 0x46 +Scroll_Lock 0x46 + +# evdev 71 (0x47), QKeyCode "kp_7", number 0x47 +KP_Home 0x47 +KP_7 0x47 numlock + +# evdev 72 (0x48), QKeyCode "kp_8", number 0x48 +KP_Up 0x48 +KP_8 0x48 numlock + +# evdev 73 (0x49), QKeyCode "kp_9", number 0x49 +KP_Prior 0x49 +KP_9 0x49 numlock + +# evdev 74 (0x4a), QKeyCode "kp_subtract", number 0x4a +KP_Subtract 0x4a + +# evdev 75 (0x4b), QKeyCode "kp_4", number 0x4b +KP_Left 0x4b +KP_4 0x4b numlock + +# evdev 76 (0x4c), QKeyCode "kp_5", number 0x4c +KP_Begin 0x4c +KP_5 0x4c numlock + +# evdev 77 (0x4d), QKeyCode "kp_6", number 0x4d +KP_Right 0x4d +KP_6 0x4d numlock + +# evdev 78 (0x4e), QKeyCode "kp_add", number 0x4e +KP_Add 0x4e + +# evdev 79 (0x4f), QKeyCode "kp_1", number 0x4f +KP_End 0x4f +KP_1 0x4f numlock + +# evdev 80 (0x50), QKeyCode "kp_2", number 0x50 +KP_Down 0x50 +KP_2 0x50 numlock + +# evdev 81 (0x51), QKeyCode "kp_3", number 0x51 +KP_Next 0x51 +KP_3 0x51 numlock + +# evdev 82 (0x52), QKeyCode "kp_0", number 0x52 +KP_Insert 0x52 +KP_0 0x52 numlock + +# evdev 83 (0x53), QKeyCode "kp_decimal", number 0x53 +KP_Delete 0x53 +KP_Decimal 0x53 numlock + +# evdev 84 (0x54): no evdev -> QKeyCode mapping (xkb keysym ISO_Level3_Shift) + +# evdev 85 (0x55): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 86 (0x56), QKeyCode "less", number 0x56 +less 0x56 +greater 0x56 shift +guillemotleft 0x56 altgr +guillemotright 0x56 shift altgr + +# evdev 87 (0x57), QKeyCode "f11", number 0x57 +F11 0x57 + +# evdev 88 (0x58), QKeyCode "f12", number 0x58 +F12 0x58 + +# evdev 89 (0x59), QKeyCode "ro", number 0x73 + +# evdev 90 (0x5a): no evdev -> QKeyCode mapping (xkb keysym Katakana) + +# evdev 91 (0x5b), QKeyCode "hiragana", number 0x77 +Hiragana 0x77 + +# evdev 92 (0x5c), QKeyCode "henkan", number 0x79 +Henkan_Mode 0x79 + +# evdev 93 (0x5d), QKeyCode "katakanahiragana", number 0x70 +Hiragana_Katakana 0x70 + +# evdev 94 (0x5e), QKeyCode "muhenkan", number 0x7b +Muhenkan 0x7b + +# evdev 95 (0x5f): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 96 (0x60), QKeyCode "kp_enter", number 0x9c +KP_Enter 0x9c + +# evdev 97 (0x61), QKeyCode "ctrl_r", number 0x9d +Control_R 0x9d + +# evdev 98 (0x62), QKeyCode "kp_divide", number 0xb5 +KP_Divide 0xb5 + +# evdev 99 (0x63), QKeyCode "sysrq", number 0x54 +Print 0x54 + +# evdev 100 (0x64), QKeyCode "alt_r", number 0xb8 +ISO_Level3_Shift 0xb8 + +# evdev 101 (0x65), QKeyCode "lf", number 0x5b +Linefeed 0x5b + +# evdev 102 (0x66), QKeyCode "home", number 0xc7 +Home 0xc7 + +# evdev 103 (0x67), QKeyCode "up", number 0xc8 +Up 0xc8 + +# evdev 104 (0x68), QKeyCode "pgup", number 0xc9 +Prior 0xc9 + +# evdev 105 (0x69), QKeyCode "left", number 0xcb +Left 0xcb + +# evdev 106 (0x6a), QKeyCode "right", number 0xcd +Right 0xcd + +# evdev 107 (0x6b), QKeyCode "end", number 0xcf +End 0xcf + +# evdev 108 (0x6c), QKeyCode "down", number 0xd0 +Down 0xd0 + +# evdev 109 (0x6d), QKeyCode "pgdn", number 0xd1 +Next 0xd1 + +# evdev 110 (0x6e), QKeyCode "insert", number 0xd2 +Insert 0xd2 + +# evdev 111 (0x6f), QKeyCode "delete", number 0xd3 +Delete 0xd3 + +# evdev 112 (0x70): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 113 (0x71), QKeyCode "audiomute", number 0xa0 +XF86AudioMute 0xa0 + +# evdev 114 (0x72), QKeyCode "volumedown", number 0xae +XF86AudioLowerVolume 0xae + +# evdev 115 (0x73), QKeyCode "volumeup", number 0xb0 +XF86AudioRaiseVolume 0xb0 + +# evdev 116 (0x74), QKeyCode "power", number 0xde +XF86PowerOff 0xde + +# evdev 117 (0x75), QKeyCode "kp_equals", number 0x59 +KP_Equal 0x59 + +# evdev 118 (0x76): no evdev -> QKeyCode mapping (xkb keysym plusminus) + +# evdev 119 (0x77), QKeyCode "pause", number 0xc6 +Pause 0xc6 + +# evdev 120 (0x78): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchA) + +# evdev 121 (0x79), QKeyCode "kp_comma", number 0x7e +KP_Decimal 0x7e + +# evdev 122 (0x7a): no evdev -> QKeyCode mapping (xkb keysym Hangul) + +# evdev 123 (0x7b): no evdev -> QKeyCode mapping (xkb keysym Hangul_Hanja) + +# evdev 124 (0x7c), QKeyCode "yen", number 0x7d + +# evdev 125 (0x7d), QKeyCode "meta_l", number 0xdb +Super_L 0xdb + +# evdev 126 (0x7e), QKeyCode "meta_r", number 0xdc +Super_R 0xdc + +# evdev 127 (0x7f), QKeyCode "compose", number 0xdd +Menu 0xdd + +# evdev 128 (0x80), QKeyCode "stop", number 0xe8 +Cancel 0xe8 + +# evdev 129 (0x81), QKeyCode "again", number 0x85 +Redo 0x85 + +# evdev 130 (0x82), QKeyCode "props", number 0x86 +SunProps 0x86 + +# evdev 131 (0x83), QKeyCode "undo", number 0x87 +Undo 0x87 + +# evdev 132 (0x84), QKeyCode "front", number 0x8c +SunFront 0x8c + +# evdev 133 (0x85), QKeyCode "copy", number 0xf8 +XF86Copy 0xf8 + +# evdev 134 (0x86), QKeyCode "open", number 0x64 +XF86Open 0x64 + +# evdev 135 (0x87), QKeyCode "paste", number 0x65 +XF86Paste 0x65 + +# evdev 136 (0x88), QKeyCode "find", number 0xc1 +Find 0xc1 + +# evdev 137 (0x89), QKeyCode "cut", number 0xbc +XF86Cut 0xbc + +# evdev 138 (0x8a), QKeyCode "help", number 0xf5 +Help 0xf5 + +# evdev 139 (0x8b), QKeyCode "menu", number 0x9e +XF86MenuKB 0x9e + +# evdev 140 (0x8c), QKeyCode "calculator", number 0xa1 +XF86Calculator 0xa1 + +# evdev 141 (0x8d): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 142 (0x8e), QKeyCode "sleep", number 0xdf +XF86Sleep 0xdf + +# evdev 143 (0x8f), QKeyCode "wake", number 0xe3 +XF86WakeUp 0xe3 + +# evdev 144 (0x90): no evdev -> QKeyCode mapping (xkb keysym XF86Explorer) + +# evdev 145 (0x91): no evdev -> QKeyCode mapping (xkb keysym XF86Send) + +# evdev 146 (0x92): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 147 (0x93): no evdev -> QKeyCode mapping (xkb keysym XF86Xfer) + +# evdev 148 (0x94): no evdev -> QKeyCode mapping (xkb keysym XF86Launch1) + +# evdev 149 (0x95): no evdev -> QKeyCode mapping (xkb keysym XF86Launch2) + +# evdev 150 (0x96): no evdev -> QKeyCode mapping (xkb keysym XF86WWW) + +# evdev 151 (0x97): no evdev -> QKeyCode mapping (xkb keysym XF86DOS) + +# evdev 152 (0x98): no evdev -> QKeyCode mapping (xkb keysym XF86ScreenSaver) + +# evdev 153 (0x99): no evdev -> QKeyCode mapping (xkb keysym XF86RotateWindows) + +# evdev 154 (0x9a): no evdev -> QKeyCode mapping (xkb keysym XF86TaskPane) + +# evdev 155 (0x9b), QKeyCode "mail", number 0xec +XF86Mail 0xec + +# evdev 156 (0x9c), QKeyCode "ac_bookmarks", number 0xe6 +XF86Favorites 0xe6 + +# evdev 157 (0x9d), QKeyCode "computer", number 0xeb +XF86MyComputer 0xeb + +# evdev 158 (0x9e), QKeyCode "ac_back", number 0xea +XF86Back 0xea + +# evdev 159 (0x9f), QKeyCode "ac_forward", number 0xe9 +XF86Forward 0xe9 + +# evdev 160 (0xa0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 161 (0xa1): no evdev -> QKeyCode mapping (xkb keysym XF86Eject) + +# evdev 162 (0xa2): no evdev -> QKeyCode mapping (xkb keysym XF86Eject) + +# evdev 163 (0xa3), QKeyCode "audionext", number 0x99 +XF86AudioNext 0x99 + +# evdev 164 (0xa4), QKeyCode "audioplay", number 0xa2 +XF86AudioPlay 0xa2 +XF86AudioPause 0xa2 shift + +# evdev 165 (0xa5), QKeyCode "audioprev", number 0x90 +XF86AudioPrev 0x90 + +# evdev 166 (0xa6), QKeyCode "audiostop", number 0xa4 +XF86AudioStop 0xa4 +XF86Eject 0xa4 shift + +# evdev 167 (0xa7): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRecord) + +# evdev 168 (0xa8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRewind) + +# evdev 169 (0xa9): no evdev -> QKeyCode mapping (xkb keysym XF86Phone) + +# evdev 170 (0xaa): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 171 (0xab): no evdev -> QKeyCode mapping (xkb keysym XF86Tools) + +# evdev 172 (0xac), QKeyCode "ac_home", number 0xb2 +XF86HomePage 0xb2 + +# evdev 173 (0xad), QKeyCode "ac_refresh", number 0xe7 +XF86Reload 0xe7 + +# evdev 174 (0xae): no evdev -> QKeyCode mapping (xkb keysym XF86Close) + +# evdev 175 (0xaf): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 176 (0xb0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 177 (0xb1): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollUp) + +# evdev 178 (0xb2): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollDown) + +# evdev 179 (0xb3): no evdev -> QKeyCode mapping (xkb keysym parenleft) + +# evdev 180 (0xb4): no evdev -> QKeyCode mapping (xkb keysym parenright) + +# evdev 181 (0xb5): no evdev -> QKeyCode mapping (xkb keysym XF86New) + +# evdev 182 (0xb6): no evdev -> QKeyCode mapping (xkb keysym Redo) + +# evdev 183 (0xb7): no evdev -> QKeyCode mapping (xkb keysym XF86Tools) + +# evdev 184 (0xb8): no evdev -> QKeyCode mapping (xkb keysym XF86Launch5) + +# evdev 185 (0xb9): no evdev -> QKeyCode mapping (xkb keysym XF86Launch6) + +# evdev 186 (0xba): no evdev -> QKeyCode mapping (xkb keysym XF86Launch7) + +# evdev 187 (0xbb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch8) + +# evdev 188 (0xbc): no evdev -> QKeyCode mapping (xkb keysym XF86Launch9) + +# evdev 189 (0xbd): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 190 (0xbe): no evdev -> QKeyCode mapping (xkb keysym XF86AudioMicMute) + +# evdev 191 (0xbf): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadToggle) + +# evdev 192 (0xc0): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOn) + +# evdev 193 (0xc1): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOff) + +# evdev 194 (0xc2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 195 (0xc3): no evdev -> QKeyCode mapping (xkb keysym Mode_switch) + +# evdev 196 (0xc4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 197 (0xc5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 198 (0xc6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 199 (0xc7): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 200 (0xc8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay) + +# evdev 201 (0xc9): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPause) + +# evdev 202 (0xca): no evdev -> QKeyCode mapping (xkb keysym XF86Launch3) + +# evdev 203 (0xcb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch4) + +# evdev 204 (0xcc): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchB) + +# evdev 205 (0xcd): no evdev -> QKeyCode mapping (xkb keysym XF86Suspend) + +# evdev 206 (0xce): no evdev -> QKeyCode mapping (xkb keysym XF86Close) + +# evdev 207 (0xcf): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay) + +# evdev 208 (0xd0): no evdev -> QKeyCode mapping (xkb keysym XF86AudioForward) + +# evdev 209 (0xd1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 210 (0xd2): no evdev -> QKeyCode mapping (xkb keysym Print) + +# evdev 211 (0xd3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 212 (0xd4): no evdev -> QKeyCode mapping (xkb keysym XF86WebCam) + +# evdev 213 (0xd5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 214 (0xd6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 215 (0xd7): no evdev -> QKeyCode mapping (xkb keysym XF86Mail) + +# evdev 216 (0xd8): no evdev -> QKeyCode mapping (xkb keysym XF86Messenger) + +# evdev 217 (0xd9): no evdev -> QKeyCode mapping (xkb keysym XF86Search) + +# evdev 218 (0xda): no evdev -> QKeyCode mapping (xkb keysym XF86Go) + +# evdev 219 (0xdb): no evdev -> QKeyCode mapping (xkb keysym XF86Finance) + +# evdev 220 (0xdc): no evdev -> QKeyCode mapping (xkb keysym XF86Game) + +# evdev 221 (0xdd): no evdev -> QKeyCode mapping (xkb keysym XF86Shop) + +# evdev 222 (0xde): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 223 (0xdf): no evdev -> QKeyCode mapping (xkb keysym Cancel) + +# evdev 224 (0xe0): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessDown) + +# evdev 225 (0xe1): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessUp) + +# evdev 226 (0xe2), QKeyCode "mediaselect", number 0xed +XF86AudioMedia 0xed + +# evdev 227 (0xe3): no evdev -> QKeyCode mapping (xkb keysym XF86Display) + +# evdev 228 (0xe4): no evdev -> QKeyCode mapping (xkb keysym XF86KbdLightOnOff) + +# evdev 229 (0xe5): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessDown) + +# evdev 230 (0xe6): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessUp) + +# evdev 231 (0xe7): no evdev -> QKeyCode mapping (xkb keysym XF86Send) + +# evdev 232 (0xe8): no evdev -> QKeyCode mapping (xkb keysym XF86Reply) + +# evdev 233 (0xe9): no evdev -> QKeyCode mapping (xkb keysym XF86MailForward) + +# evdev 234 (0xea): no evdev -> QKeyCode mapping (xkb keysym XF86Save) + +# evdev 235 (0xeb): no evdev -> QKeyCode mapping (xkb keysym XF86Documents) + +# evdev 236 (0xec): no evdev -> QKeyCode mapping (xkb keysym XF86Battery) + +# evdev 237 (0xed): no evdev -> QKeyCode mapping (xkb keysym XF86Bluetooth) + +# evdev 238 (0xee): no evdev -> QKeyCode mapping (xkb keysym XF86WLAN) + +# evdev 239 (0xef): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 240 (0xf0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 241 (0xf1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 242 (0xf2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 243 (0xf3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 244 (0xf4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 245 (0xf5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 246 (0xf6): no evdev -> QKeyCode mapping (xkb keysym Invalid) + +# evdev 247 (0xf7): no evdev -> QKeyCode mapping (xkb keysym Invalid) + +# +# quirks section start +# +# Sometimes multiple keysyms map to the same keycodes. +# The keycode -> keysym lookup finds only one of the +# keysyms. So append them here. +# + +Print 0x54 +Sys_Req 0x54 +Execute 0x54 +KP_Decimal 0x53 numlock +KP_Separator 0x53 numlock +Alt_R 0xb8 +ISO_Level3_Shift 0xb8 +Mode_switch 0xb8 + +# quirks section end diff --git a/app/src/main/assets/roms/keymaps/ja b/app/src/main/assets/roms/keymaps/ja new file mode 100644 index 0000000..6eb2e7b --- /dev/null +++ b/app/src/main/assets/roms/keymaps/ja @@ -0,0 +1,757 @@ +# +# generated by qemu-keymap +# model : jp106 +# layout : jp +# variant : - +# options : - + +# name: "Japanese" + +# modifiers +# 0: Shift +# 1: Lock +# 2: Control +# 3: Mod1 +# 4: Mod2 +# 5: Mod3 +# 6: Mod4 +# 7: Mod5 +# 8: NumLock +# 9: Alt +# 10: LevelThree +# 11: LAlt +# 12: RAlt +# 13: RControl +# 14: LControl +# 15: ScrollLock +# 16: LevelFive +# 17: AltGr +# 18: Meta +# 19: Super +# 20: Hyper + +# evdev 1 (0x1), QKeyCode "esc", number 0x1 +Escape 0x01 + +# evdev 2 (0x2), QKeyCode "1", number 0x2 +1 0x02 +exclam 0x02 shift + +# evdev 3 (0x3), QKeyCode "2", number 0x3 +2 0x03 +quotedbl 0x03 shift + +# evdev 4 (0x4), QKeyCode "3", number 0x4 +3 0x04 +numbersign 0x04 shift + +# evdev 5 (0x5), QKeyCode "4", number 0x5 +4 0x05 +dollar 0x05 shift + +# evdev 6 (0x6), QKeyCode "5", number 0x6 +5 0x06 +percent 0x06 shift + +# evdev 7 (0x7), QKeyCode "6", number 0x7 +6 0x07 +ampersand 0x07 shift + +# evdev 8 (0x8), QKeyCode "7", number 0x8 +7 0x08 +apostrophe 0x08 shift + +# evdev 9 (0x9), QKeyCode "8", number 0x9 +8 0x09 +parenleft 0x09 shift + +# evdev 10 (0xa), QKeyCode "9", number 0xa +9 0x0a +parenright 0x0a shift + +# evdev 11 (0xb), QKeyCode "0", number 0xb +0 0x0b +asciitilde 0x0b shift + +# evdev 12 (0xc), QKeyCode "minus", number 0xc +minus 0x0c +equal 0x0c shift + +# evdev 13 (0xd), QKeyCode "equal", number 0xd +asciicircum 0x0d +asciitilde 0x0d shift + +# evdev 14 (0xe), QKeyCode "backspace", number 0xe +BackSpace 0x0e + +# evdev 15 (0xf), QKeyCode "tab", number 0xf +Tab 0x0f +ISO_Left_Tab 0x0f shift + +# evdev 16 (0x10), QKeyCode "q", number 0x10 +q 0x10 +Q 0x10 shift + +# evdev 17 (0x11), QKeyCode "w", number 0x11 +w 0x11 +W 0x11 shift + +# evdev 18 (0x12), QKeyCode "e", number 0x12 +e 0x12 +E 0x12 shift + +# evdev 19 (0x13), QKeyCode "r", number 0x13 +r 0x13 +R 0x13 shift + +# evdev 20 (0x14), QKeyCode "t", number 0x14 +t 0x14 +T 0x14 shift + +# evdev 21 (0x15), QKeyCode "y", number 0x15 +y 0x15 +Y 0x15 shift + +# evdev 22 (0x16), QKeyCode "u", number 0x16 +u 0x16 +U 0x16 shift + +# evdev 23 (0x17), QKeyCode "i", number 0x17 +i 0x17 +I 0x17 shift + +# evdev 24 (0x18), QKeyCode "o", number 0x18 +o 0x18 +O 0x18 shift + +# evdev 25 (0x19), QKeyCode "p", number 0x19 +p 0x19 +P 0x19 shift + +# evdev 26 (0x1a), QKeyCode "bracket_left", number 0x1a +at 0x1a +grave 0x1a shift + +# evdev 27 (0x1b), QKeyCode "bracket_right", number 0x1b +bracketleft 0x1b +braceleft 0x1b shift + +# evdev 28 (0x1c), QKeyCode "ret", number 0x1c +Return 0x1c + +# evdev 29 (0x1d), QKeyCode "ctrl", number 0x1d +Control_L 0x1d + +# evdev 30 (0x1e), QKeyCode "a", number 0x1e +a 0x1e +A 0x1e shift + +# evdev 31 (0x1f), QKeyCode "s", number 0x1f +s 0x1f +S 0x1f shift + +# evdev 32 (0x20), QKeyCode "d", number 0x20 +d 0x20 +D 0x20 shift + +# evdev 33 (0x21), QKeyCode "f", number 0x21 +f 0x21 +F 0x21 shift + +# evdev 34 (0x22), QKeyCode "g", number 0x22 +g 0x22 +G 0x22 shift + +# evdev 35 (0x23), QKeyCode "h", number 0x23 +h 0x23 +H 0x23 shift + +# evdev 36 (0x24), QKeyCode "j", number 0x24 +j 0x24 +J 0x24 shift + +# evdev 37 (0x25), QKeyCode "k", number 0x25 +k 0x25 +K 0x25 shift + +# evdev 38 (0x26), QKeyCode "l", number 0x26 +l 0x26 +L 0x26 shift + +# evdev 39 (0x27), QKeyCode "semicolon", number 0x27 +semicolon 0x27 +plus 0x27 shift + +# evdev 40 (0x28), QKeyCode "apostrophe", number 0x28 +colon 0x28 +asterisk 0x28 shift + +# evdev 41 (0x29), QKeyCode "grave_accent", number 0x29 +Zenkaku_Hankaku 0x29 + +# evdev 42 (0x2a), QKeyCode "shift", number 0x2a +Shift_L 0x2a + +# evdev 43 (0x2b), QKeyCode "backslash", number 0x2b +bracketright 0x2b +braceright 0x2b shift + +# evdev 44 (0x2c), QKeyCode "z", number 0x2c +z 0x2c +Z 0x2c shift + +# evdev 45 (0x2d), QKeyCode "x", number 0x2d +x 0x2d +X 0x2d shift + +# evdev 46 (0x2e), QKeyCode "c", number 0x2e +c 0x2e +C 0x2e shift + +# evdev 47 (0x2f), QKeyCode "v", number 0x2f +v 0x2f +V 0x2f shift + +# evdev 48 (0x30), QKeyCode "b", number 0x30 +b 0x30 +B 0x30 shift + +# evdev 49 (0x31), QKeyCode "n", number 0x31 +n 0x31 +N 0x31 shift + +# evdev 50 (0x32), QKeyCode "m", number 0x32 +m 0x32 +M 0x32 shift + +# evdev 51 (0x33), QKeyCode "comma", number 0x33 +comma 0x33 +less 0x33 shift + +# evdev 52 (0x34), QKeyCode "dot", number 0x34 +period 0x34 +greater 0x34 shift + +# evdev 53 (0x35), QKeyCode "slash", number 0x35 +slash 0x35 +question 0x35 shift + +# evdev 54 (0x36), QKeyCode "shift_r", number 0x36 +Shift_R 0x36 + +# evdev 55 (0x37), QKeyCode "kp_multiply", number 0x37 +KP_Multiply 0x37 + +# evdev 56 (0x38), QKeyCode "alt", number 0x38 +Alt_L 0x38 +Meta_L 0x38 shift + +# evdev 57 (0x39), QKeyCode "spc", number 0x39 +space 0x39 + +# evdev 58 (0x3a), QKeyCode "caps_lock", number 0x3a +Eisu_toggle 0x3a +Caps_Lock 0x3a shift + +# evdev 59 (0x3b), QKeyCode "f1", number 0x3b +F1 0x3b + +# evdev 60 (0x3c), QKeyCode "f2", number 0x3c +F2 0x3c + +# evdev 61 (0x3d), QKeyCode "f3", number 0x3d +F3 0x3d + +# evdev 62 (0x3e), QKeyCode "f4", number 0x3e +F4 0x3e + +# evdev 63 (0x3f), QKeyCode "f5", number 0x3f +F5 0x3f + +# evdev 64 (0x40), QKeyCode "f6", number 0x40 +F6 0x40 + +# evdev 65 (0x41), QKeyCode "f7", number 0x41 +F7 0x41 + +# evdev 66 (0x42), QKeyCode "f8", number 0x42 +F8 0x42 + +# evdev 67 (0x43), QKeyCode "f9", number 0x43 +F9 0x43 + +# evdev 68 (0x44), QKeyCode "f10", number 0x44 +F10 0x44 + +# evdev 69 (0x45), QKeyCode "num_lock", number 0x45 +Num_Lock 0x45 + +# evdev 70 (0x46), QKeyCode "scroll_lock", number 0x46 +Scroll_Lock 0x46 + +# evdev 71 (0x47), QKeyCode "kp_7", number 0x47 +KP_Home 0x47 +KP_7 0x47 numlock + +# evdev 72 (0x48), QKeyCode "kp_8", number 0x48 +KP_Up 0x48 +KP_8 0x48 numlock + +# evdev 73 (0x49), QKeyCode "kp_9", number 0x49 +KP_Prior 0x49 +KP_9 0x49 numlock + +# evdev 74 (0x4a), QKeyCode "kp_subtract", number 0x4a +KP_Subtract 0x4a + +# evdev 75 (0x4b), QKeyCode "kp_4", number 0x4b +KP_Left 0x4b +KP_4 0x4b numlock + +# evdev 76 (0x4c), QKeyCode "kp_5", number 0x4c +KP_Begin 0x4c +KP_5 0x4c numlock + +# evdev 77 (0x4d), QKeyCode "kp_6", number 0x4d +KP_Right 0x4d +KP_6 0x4d numlock + +# evdev 78 (0x4e), QKeyCode "kp_add", number 0x4e +KP_Add 0x4e + +# evdev 79 (0x4f), QKeyCode "kp_1", number 0x4f +KP_End 0x4f +KP_1 0x4f numlock + +# evdev 80 (0x50), QKeyCode "kp_2", number 0x50 +KP_Down 0x50 +KP_2 0x50 numlock + +# evdev 81 (0x51), QKeyCode "kp_3", number 0x51 +KP_Next 0x51 +KP_3 0x51 numlock + +# evdev 82 (0x52), QKeyCode "kp_0", number 0x52 +KP_Insert 0x52 +KP_0 0x52 numlock + +# evdev 83 (0x53), QKeyCode "kp_decimal", number 0x53 +KP_Delete 0x53 +KP_Decimal 0x53 numlock + +# evdev 84 (0x54): no evdev -> QKeyCode mapping (xkb keysym ISO_Level3_Shift) + +# evdev 85 (0x55): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 86 (0x56), QKeyCode "less", number 0x56 +less 0x56 +greater 0x56 shift +bar 0x56 altgr +brokenbar 0x56 shift altgr + +# evdev 87 (0x57), QKeyCode "f11", number 0x57 +F11 0x57 + +# evdev 88 (0x58), QKeyCode "f12", number 0x58 +F12 0x58 + +# evdev 89 (0x59), QKeyCode "ro", number 0x73 +backslash 0x73 +underscore 0x73 shift + +# evdev 90 (0x5a): no evdev -> QKeyCode mapping (xkb keysym Katakana) + +# evdev 91 (0x5b), QKeyCode "hiragana", number 0x77 +Hiragana 0x77 + +# evdev 92 (0x5c), QKeyCode "henkan", number 0x79 +Henkan_Mode 0x79 + +# evdev 93 (0x5d), QKeyCode "katakanahiragana", number 0x70 +Hiragana_Katakana 0x70 + +# evdev 94 (0x5e), QKeyCode "muhenkan", number 0x7b +Muhenkan 0x7b + +# evdev 95 (0x5f): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 96 (0x60), QKeyCode "kp_enter", number 0x9c +KP_Enter 0x9c + +# evdev 97 (0x61), QKeyCode "ctrl_r", number 0x9d +Control_R 0x9d + +# evdev 98 (0x62), QKeyCode "kp_divide", number 0xb5 +KP_Divide 0xb5 + +# evdev 99 (0x63), QKeyCode "sysrq", number 0x54 +Print 0x54 + +# evdev 100 (0x64), QKeyCode "alt_r", number 0xb8 +Alt_R 0xb8 +Meta_R 0xb8 shift + +# evdev 101 (0x65), QKeyCode "lf", number 0x5b +Linefeed 0x5b + +# evdev 102 (0x66), QKeyCode "home", number 0xc7 +Home 0xc7 + +# evdev 103 (0x67), QKeyCode "up", number 0xc8 +Up 0xc8 + +# evdev 104 (0x68), QKeyCode "pgup", number 0xc9 +Prior 0xc9 + +# evdev 105 (0x69), QKeyCode "left", number 0xcb +Left 0xcb + +# evdev 106 (0x6a), QKeyCode "right", number 0xcd +Right 0xcd + +# evdev 107 (0x6b), QKeyCode "end", number 0xcf +End 0xcf + +# evdev 108 (0x6c), QKeyCode "down", number 0xd0 +Down 0xd0 + +# evdev 109 (0x6d), QKeyCode "pgdn", number 0xd1 +Next 0xd1 + +# evdev 110 (0x6e), QKeyCode "insert", number 0xd2 +Insert 0xd2 + +# evdev 111 (0x6f), QKeyCode "delete", number 0xd3 +Delete 0xd3 + +# evdev 112 (0x70): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 113 (0x71), QKeyCode "audiomute", number 0xa0 +XF86AudioMute 0xa0 + +# evdev 114 (0x72), QKeyCode "volumedown", number 0xae +XF86AudioLowerVolume 0xae + +# evdev 115 (0x73), QKeyCode "volumeup", number 0xb0 +XF86AudioRaiseVolume 0xb0 + +# evdev 116 (0x74), QKeyCode "power", number 0xde +XF86PowerOff 0xde + +# evdev 117 (0x75), QKeyCode "kp_equals", number 0x59 +KP_Equal 0x59 + +# evdev 118 (0x76): no evdev -> QKeyCode mapping (xkb keysym plusminus) + +# evdev 119 (0x77), QKeyCode "pause", number 0xc6 +Pause 0xc6 + +# evdev 120 (0x78): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchA) + +# evdev 121 (0x79), QKeyCode "kp_comma", number 0x7e +KP_Decimal 0x7e + +# evdev 122 (0x7a): no evdev -> QKeyCode mapping (xkb keysym Hangul) + +# evdev 123 (0x7b): no evdev -> QKeyCode mapping (xkb keysym Hangul_Hanja) + +# evdev 124 (0x7c), QKeyCode "yen", number 0x7d +backslash 0x7d +bar 0x7d shift + +# evdev 125 (0x7d), QKeyCode "meta_l", number 0xdb +Super_L 0xdb + +# evdev 126 (0x7e), QKeyCode "meta_r", number 0xdc +Super_R 0xdc + +# evdev 127 (0x7f), QKeyCode "compose", number 0xdd +Menu 0xdd + +# evdev 128 (0x80), QKeyCode "stop", number 0xe8 +Cancel 0xe8 + +# evdev 129 (0x81), QKeyCode "again", number 0x85 +Redo 0x85 + +# evdev 130 (0x82), QKeyCode "props", number 0x86 +SunProps 0x86 + +# evdev 131 (0x83), QKeyCode "undo", number 0x87 +Undo 0x87 + +# evdev 132 (0x84), QKeyCode "front", number 0x8c +SunFront 0x8c + +# evdev 133 (0x85), QKeyCode "copy", number 0xf8 +XF86Copy 0xf8 + +# evdev 134 (0x86), QKeyCode "open", number 0x64 +XF86Open 0x64 + +# evdev 135 (0x87), QKeyCode "paste", number 0x65 +XF86Paste 0x65 + +# evdev 136 (0x88), QKeyCode "find", number 0xc1 +Find 0xc1 + +# evdev 137 (0x89), QKeyCode "cut", number 0xbc +XF86Cut 0xbc + +# evdev 138 (0x8a), QKeyCode "help", number 0xf5 +Help 0xf5 + +# evdev 139 (0x8b), QKeyCode "menu", number 0x9e +XF86MenuKB 0x9e + +# evdev 140 (0x8c), QKeyCode "calculator", number 0xa1 +XF86Calculator 0xa1 + +# evdev 141 (0x8d): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 142 (0x8e), QKeyCode "sleep", number 0xdf +XF86Sleep 0xdf + +# evdev 143 (0x8f), QKeyCode "wake", number 0xe3 +XF86WakeUp 0xe3 + +# evdev 144 (0x90): no evdev -> QKeyCode mapping (xkb keysym XF86Explorer) + +# evdev 145 (0x91): no evdev -> QKeyCode mapping (xkb keysym XF86Send) + +# evdev 146 (0x92): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 147 (0x93): no evdev -> QKeyCode mapping (xkb keysym XF86Xfer) + +# evdev 148 (0x94): no evdev -> QKeyCode mapping (xkb keysym XF86Launch1) + +# evdev 149 (0x95): no evdev -> QKeyCode mapping (xkb keysym XF86Launch2) + +# evdev 150 (0x96): no evdev -> QKeyCode mapping (xkb keysym XF86WWW) + +# evdev 151 (0x97): no evdev -> QKeyCode mapping (xkb keysym XF86DOS) + +# evdev 152 (0x98): no evdev -> QKeyCode mapping (xkb keysym XF86ScreenSaver) + +# evdev 153 (0x99): no evdev -> QKeyCode mapping (xkb keysym XF86RotateWindows) + +# evdev 154 (0x9a): no evdev -> QKeyCode mapping (xkb keysym XF86TaskPane) + +# evdev 155 (0x9b), QKeyCode "mail", number 0xec +XF86Mail 0xec + +# evdev 156 (0x9c), QKeyCode "ac_bookmarks", number 0xe6 +XF86Favorites 0xe6 + +# evdev 157 (0x9d), QKeyCode "computer", number 0xeb +XF86MyComputer 0xeb + +# evdev 158 (0x9e), QKeyCode "ac_back", number 0xea +XF86Back 0xea + +# evdev 159 (0x9f), QKeyCode "ac_forward", number 0xe9 +XF86Forward 0xe9 + +# evdev 160 (0xa0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 161 (0xa1): no evdev -> QKeyCode mapping (xkb keysym XF86Eject) + +# evdev 162 (0xa2): no evdev -> QKeyCode mapping (xkb keysym XF86Eject) + +# evdev 163 (0xa3), QKeyCode "audionext", number 0x99 +XF86AudioNext 0x99 + +# evdev 164 (0xa4), QKeyCode "audioplay", number 0xa2 +XF86AudioPlay 0xa2 +XF86AudioPause 0xa2 shift + +# evdev 165 (0xa5), QKeyCode "audioprev", number 0x90 +XF86AudioPrev 0x90 + +# evdev 166 (0xa6), QKeyCode "audiostop", number 0xa4 +XF86AudioStop 0xa4 +XF86Eject 0xa4 shift + +# evdev 167 (0xa7): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRecord) + +# evdev 168 (0xa8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRewind) + +# evdev 169 (0xa9): no evdev -> QKeyCode mapping (xkb keysym XF86Phone) + +# evdev 170 (0xaa): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 171 (0xab): no evdev -> QKeyCode mapping (xkb keysym XF86Tools) + +# evdev 172 (0xac), QKeyCode "ac_home", number 0xb2 +XF86HomePage 0xb2 + +# evdev 173 (0xad), QKeyCode "ac_refresh", number 0xe7 +XF86Reload 0xe7 + +# evdev 174 (0xae): no evdev -> QKeyCode mapping (xkb keysym XF86Close) + +# evdev 175 (0xaf): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 176 (0xb0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 177 (0xb1): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollUp) + +# evdev 178 (0xb2): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollDown) + +# evdev 179 (0xb3): no evdev -> QKeyCode mapping (xkb keysym parenleft) + +# evdev 180 (0xb4): no evdev -> QKeyCode mapping (xkb keysym parenright) + +# evdev 181 (0xb5): no evdev -> QKeyCode mapping (xkb keysym XF86New) + +# evdev 182 (0xb6): no evdev -> QKeyCode mapping (xkb keysym Redo) + +# evdev 183 (0xb7): no evdev -> QKeyCode mapping (xkb keysym XF86Tools) + +# evdev 184 (0xb8): no evdev -> QKeyCode mapping (xkb keysym XF86Launch5) + +# evdev 185 (0xb9): no evdev -> QKeyCode mapping (xkb keysym XF86Launch6) + +# evdev 186 (0xba): no evdev -> QKeyCode mapping (xkb keysym XF86Launch7) + +# evdev 187 (0xbb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch8) + +# evdev 188 (0xbc): no evdev -> QKeyCode mapping (xkb keysym XF86Launch9) + +# evdev 189 (0xbd): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 190 (0xbe): no evdev -> QKeyCode mapping (xkb keysym XF86AudioMicMute) + +# evdev 191 (0xbf): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadToggle) + +# evdev 192 (0xc0): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOn) + +# evdev 193 (0xc1): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOff) + +# evdev 194 (0xc2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 195 (0xc3): no evdev -> QKeyCode mapping (xkb keysym Mode_switch) + +# evdev 196 (0xc4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 197 (0xc5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 198 (0xc6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 199 (0xc7): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 200 (0xc8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay) + +# evdev 201 (0xc9): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPause) + +# evdev 202 (0xca): no evdev -> QKeyCode mapping (xkb keysym XF86Launch3) + +# evdev 203 (0xcb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch4) + +# evdev 204 (0xcc): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchB) + +# evdev 205 (0xcd): no evdev -> QKeyCode mapping (xkb keysym XF86Suspend) + +# evdev 206 (0xce): no evdev -> QKeyCode mapping (xkb keysym XF86Close) + +# evdev 207 (0xcf): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay) + +# evdev 208 (0xd0): no evdev -> QKeyCode mapping (xkb keysym XF86AudioForward) + +# evdev 209 (0xd1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 210 (0xd2): no evdev -> QKeyCode mapping (xkb keysym Print) + +# evdev 211 (0xd3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 212 (0xd4): no evdev -> QKeyCode mapping (xkb keysym XF86WebCam) + +# evdev 213 (0xd5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 214 (0xd6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 215 (0xd7): no evdev -> QKeyCode mapping (xkb keysym XF86Mail) + +# evdev 216 (0xd8): no evdev -> QKeyCode mapping (xkb keysym XF86Messenger) + +# evdev 217 (0xd9): no evdev -> QKeyCode mapping (xkb keysym XF86Search) + +# evdev 218 (0xda): no evdev -> QKeyCode mapping (xkb keysym XF86Go) + +# evdev 219 (0xdb): no evdev -> QKeyCode mapping (xkb keysym XF86Finance) + +# evdev 220 (0xdc): no evdev -> QKeyCode mapping (xkb keysym XF86Game) + +# evdev 221 (0xdd): no evdev -> QKeyCode mapping (xkb keysym XF86Shop) + +# evdev 222 (0xde): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 223 (0xdf): no evdev -> QKeyCode mapping (xkb keysym Cancel) + +# evdev 224 (0xe0): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessDown) + +# evdev 225 (0xe1): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessUp) + +# evdev 226 (0xe2), QKeyCode "mediaselect", number 0xed +XF86AudioMedia 0xed + +# evdev 227 (0xe3): no evdev -> QKeyCode mapping (xkb keysym XF86Display) + +# evdev 228 (0xe4): no evdev -> QKeyCode mapping (xkb keysym XF86KbdLightOnOff) + +# evdev 229 (0xe5): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessDown) + +# evdev 230 (0xe6): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessUp) + +# evdev 231 (0xe7): no evdev -> QKeyCode mapping (xkb keysym XF86Send) + +# evdev 232 (0xe8): no evdev -> QKeyCode mapping (xkb keysym XF86Reply) + +# evdev 233 (0xe9): no evdev -> QKeyCode mapping (xkb keysym XF86MailForward) + +# evdev 234 (0xea): no evdev -> QKeyCode mapping (xkb keysym XF86Save) + +# evdev 235 (0xeb): no evdev -> QKeyCode mapping (xkb keysym XF86Documents) + +# evdev 236 (0xec): no evdev -> QKeyCode mapping (xkb keysym XF86Battery) + +# evdev 237 (0xed): no evdev -> QKeyCode mapping (xkb keysym XF86Bluetooth) + +# evdev 238 (0xee): no evdev -> QKeyCode mapping (xkb keysym XF86WLAN) + +# evdev 239 (0xef): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 240 (0xf0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 241 (0xf1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 242 (0xf2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 243 (0xf3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 244 (0xf4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 245 (0xf5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 246 (0xf6): no evdev -> QKeyCode mapping (xkb keysym Invalid) + +# evdev 247 (0xf7): no evdev -> QKeyCode mapping (xkb keysym Invalid) + +# +# quirks section start +# +# Sometimes multiple keysyms map to the same keycodes. +# The keycode -> keysym lookup finds only one of the +# keysyms. So append them here. +# + +Print 0x54 +Sys_Req 0x54 +Execute 0x54 +KP_Decimal 0x53 numlock +KP_Separator 0x53 numlock +Alt_R 0xb8 +ISO_Level3_Shift 0xb8 +Mode_switch 0xb8 + +# quirks section end diff --git a/app/src/main/assets/roms/keymaps/lt b/app/src/main/assets/roms/keymaps/lt new file mode 100644 index 0000000..db9b24f --- /dev/null +++ b/app/src/main/assets/roms/keymaps/lt @@ -0,0 +1,841 @@ +# +# generated by qemu-keymap +# model : pc105 +# layout : lt +# variant : - +# options : - + +# name: "Lithuanian" + +# modifiers +# 0: Shift +# 1: Lock +# 2: Control +# 3: Mod1 +# 4: Mod2 +# 5: Mod3 +# 6: Mod4 +# 7: Mod5 +# 8: NumLock +# 9: Alt +# 10: LevelThree +# 11: LAlt +# 12: RAlt +# 13: RControl +# 14: LControl +# 15: ScrollLock +# 16: LevelFive +# 17: AltGr +# 18: Meta +# 19: Super +# 20: Hyper + +# evdev 1 (0x1), QKeyCode "esc", number 0x1 +Escape 0x01 + +# evdev 2 (0x2), QKeyCode "1", number 0x2 +aogonek 0x02 +Aogonek 0x02 shift +1 0x02 altgr +exclam 0x02 shift altgr + +# evdev 3 (0x3), QKeyCode "2", number 0x3 +ccaron 0x03 +Ccaron 0x03 shift +2 0x03 altgr +at 0x03 shift altgr + +# evdev 4 (0x4), QKeyCode "3", number 0x4 +eogonek 0x04 +Eogonek 0x04 shift +3 0x04 altgr +numbersign 0x04 shift altgr + +# evdev 5 (0x5), QKeyCode "4", number 0x5 +eabovedot 0x05 +Eabovedot 0x05 shift +4 0x05 altgr +dollar 0x05 shift altgr + +# evdev 6 (0x6), QKeyCode "5", number 0x6 +iogonek 0x06 +Iogonek 0x06 shift +5 0x06 altgr +percent 0x06 shift altgr + +# evdev 7 (0x7), QKeyCode "6", number 0x7 +scaron 0x07 +Scaron 0x07 shift +6 0x07 altgr +asciicircum 0x07 shift altgr + +# evdev 8 (0x8), QKeyCode "7", number 0x8 +uogonek 0x08 +Uogonek 0x08 shift +7 0x08 altgr +ampersand 0x08 shift altgr + +# evdev 9 (0x9), QKeyCode "8", number 0x9 +umacron 0x09 +Umacron 0x09 shift +8 0x09 altgr +asterisk 0x09 shift altgr + +# evdev 10 (0xa), QKeyCode "9", number 0xa +doublelowquotemark 0x0a +parenleft 0x0a shift +9 0x0a altgr + +# evdev 11 (0xb), QKeyCode "0", number 0xb +leftdoublequotemark 0x0b +parenright 0x0b shift +0 0x0b altgr + +# evdev 12 (0xc), QKeyCode "minus", number 0xc +minus 0x0c +underscore 0x0c shift +endash 0x0c altgr +questiondown 0x0c shift altgr + +# evdev 13 (0xd), QKeyCode "equal", number 0xd +zcaron 0x0d +Zcaron 0x0d shift +equal 0x0d altgr +plus 0x0d shift altgr + +# evdev 14 (0xe), QKeyCode "backspace", number 0xe +BackSpace 0x0e + +# evdev 15 (0xf), QKeyCode "tab", number 0xf +Tab 0x0f +ISO_Left_Tab 0x0f shift + +# evdev 16 (0x10), QKeyCode "q", number 0x10 +q 0x10 +Q 0x10 shift +at 0x10 altgr +Greek_OMEGA 0x10 shift altgr + +# evdev 17 (0x11), QKeyCode "w", number 0x11 +w 0x11 +W 0x11 shift +lstroke 0x11 altgr +Lstroke 0x11 shift altgr + +# evdev 18 (0x12), QKeyCode "e", number 0x12 +e 0x12 +E 0x12 shift +EuroSign 0x12 altgr + +# evdev 19 (0x13), QKeyCode "r", number 0x13 +r 0x13 +R 0x13 shift +paragraph 0x13 altgr +registered 0x13 shift altgr + +# evdev 20 (0x14), QKeyCode "t", number 0x14 +t 0x14 +T 0x14 shift +tslash 0x14 altgr +Tslash 0x14 shift altgr + +# evdev 21 (0x15), QKeyCode "y", number 0x15 +y 0x15 +Y 0x15 shift +leftarrow 0x15 altgr +yen 0x15 shift altgr + +# evdev 22 (0x16), QKeyCode "u", number 0x16 +u 0x16 +U 0x16 shift +downarrow 0x16 altgr +uparrow 0x16 shift altgr + +# evdev 23 (0x17), QKeyCode "i", number 0x17 +i 0x17 +I 0x17 shift +rightarrow 0x17 altgr +idotless 0x17 shift altgr + +# evdev 24 (0x18), QKeyCode "o", number 0x18 +o 0x18 +O 0x18 shift +oslash 0x18 altgr +Oslash 0x18 shift altgr + +# evdev 25 (0x19), QKeyCode "p", number 0x19 +p 0x19 +P 0x19 shift +thorn 0x19 altgr +THORN 0x19 shift altgr + +# evdev 26 (0x1a), QKeyCode "bracket_left", number 0x1a +bracketleft 0x1a +braceleft 0x1a shift +dead_diaeresis 0x1a altgr +dead_abovering 0x1a shift altgr + +# evdev 27 (0x1b), QKeyCode "bracket_right", number 0x1b +bracketright 0x1b +braceright 0x1b shift +dead_tilde 0x1b altgr +dead_macron 0x1b shift altgr + +# evdev 28 (0x1c), QKeyCode "ret", number 0x1c +Return 0x1c + +# evdev 29 (0x1d), QKeyCode "ctrl", number 0x1d +Control_L 0x1d + +# evdev 30 (0x1e), QKeyCode "a", number 0x1e +a 0x1e +A 0x1e shift +ae 0x1e altgr +AE 0x1e shift altgr + +# evdev 31 (0x1f), QKeyCode "s", number 0x1f +s 0x1f +S 0x1f shift +ssharp 0x1f altgr +section 0x1f shift altgr + +# evdev 32 (0x20), QKeyCode "d", number 0x20 +d 0x20 +D 0x20 shift +eth 0x20 altgr +ETH 0x20 shift altgr + +# evdev 33 (0x21), QKeyCode "f", number 0x21 +f 0x21 +F 0x21 shift +dstroke 0x21 altgr +ordfeminine 0x21 shift altgr + +# evdev 34 (0x22), QKeyCode "g", number 0x22 +g 0x22 +G 0x22 shift +eng 0x22 altgr +ENG 0x22 shift altgr + +# evdev 35 (0x23), QKeyCode "h", number 0x23 +h 0x23 +H 0x23 shift +hstroke 0x23 altgr +Hstroke 0x23 shift altgr + +# evdev 36 (0x24), QKeyCode "j", number 0x24 +j 0x24 +J 0x24 shift +dead_hook 0x24 altgr +dead_horn 0x24 shift altgr + +# evdev 37 (0x25), QKeyCode "k", number 0x25 +k 0x25 +K 0x25 shift +kra 0x25 altgr +ampersand 0x25 shift altgr + +# evdev 38 (0x26), QKeyCode "l", number 0x26 +l 0x26 +L 0x26 shift +lstroke 0x26 altgr +Lstroke 0x26 shift altgr + +# evdev 39 (0x27), QKeyCode "semicolon", number 0x27 +semicolon 0x27 +colon 0x27 shift +dead_acute 0x27 altgr +dead_doubleacute 0x27 shift altgr + +# evdev 40 (0x28), QKeyCode "apostrophe", number 0x28 +apostrophe 0x28 +quotedbl 0x28 shift +dead_circumflex 0x28 altgr +dead_caron 0x28 shift altgr + +# evdev 41 (0x29), QKeyCode "grave_accent", number 0x29 +grave 0x29 +asciitilde 0x29 shift +acute 0x29 altgr +notsign 0x29 shift altgr + +# evdev 42 (0x2a), QKeyCode "shift", number 0x2a +Shift_L 0x2a + +# evdev 43 (0x2b), QKeyCode "backslash", number 0x2b +backslash 0x2b +bar 0x2b shift +dead_grave 0x2b altgr +dead_breve 0x2b shift altgr + +# evdev 44 (0x2c), QKeyCode "z", number 0x2c +z 0x2c +Z 0x2c shift +guillemotleft 0x2c altgr +less 0x2c shift altgr + +# evdev 45 (0x2d), QKeyCode "x", number 0x2d +x 0x2d +X 0x2d shift +guillemotright 0x2d altgr +greater 0x2d shift altgr + +# evdev 46 (0x2e), QKeyCode "c", number 0x2e +c 0x2e +C 0x2e shift +cent 0x2e altgr +copyright 0x2e shift altgr + +# evdev 47 (0x2f), QKeyCode "v", number 0x2f +v 0x2f +V 0x2f shift +leftdoublequotemark 0x2f altgr +leftsinglequotemark 0x2f shift altgr + +# evdev 48 (0x30), QKeyCode "b", number 0x30 +b 0x30 +B 0x30 shift +rightdoublequotemark 0x30 altgr +rightsinglequotemark 0x30 shift altgr + +# evdev 49 (0x31), QKeyCode "n", number 0x31 +n 0x31 +N 0x31 shift + +# evdev 50 (0x32), QKeyCode "m", number 0x32 +m 0x32 +M 0x32 shift +mu 0x32 altgr +masculine 0x32 shift altgr + +# evdev 51 (0x33), QKeyCode "comma", number 0x33 +comma 0x33 +less 0x33 shift +horizconnector 0x33 altgr +multiply 0x33 shift altgr + +# evdev 52 (0x34), QKeyCode "dot", number 0x34 +period 0x34 +greater 0x34 shift +periodcentered 0x34 altgr +division 0x34 shift altgr + +# evdev 53 (0x35), QKeyCode "slash", number 0x35 +slash 0x35 +question 0x35 shift +dead_belowdot 0x35 altgr +dead_abovedot 0x35 shift altgr + +# evdev 54 (0x36), QKeyCode "shift_r", number 0x36 +Shift_R 0x36 + +# evdev 55 (0x37), QKeyCode "kp_multiply", number 0x37 +KP_Multiply 0x37 + +# evdev 56 (0x38), QKeyCode "alt", number 0x38 +Alt_L 0x38 +Meta_L 0x38 shift + +# evdev 57 (0x39), QKeyCode "spc", number 0x39 +space 0x39 + +# evdev 58 (0x3a), QKeyCode "caps_lock", number 0x3a +Caps_Lock 0x3a + +# evdev 59 (0x3b), QKeyCode "f1", number 0x3b +F1 0x3b + +# evdev 60 (0x3c), QKeyCode "f2", number 0x3c +F2 0x3c + +# evdev 61 (0x3d), QKeyCode "f3", number 0x3d +F3 0x3d + +# evdev 62 (0x3e), QKeyCode "f4", number 0x3e +F4 0x3e + +# evdev 63 (0x3f), QKeyCode "f5", number 0x3f +F5 0x3f + +# evdev 64 (0x40), QKeyCode "f6", number 0x40 +F6 0x40 + +# evdev 65 (0x41), QKeyCode "f7", number 0x41 +F7 0x41 + +# evdev 66 (0x42), QKeyCode "f8", number 0x42 +F8 0x42 + +# evdev 67 (0x43), QKeyCode "f9", number 0x43 +F9 0x43 + +# evdev 68 (0x44), QKeyCode "f10", number 0x44 +F10 0x44 + +# evdev 69 (0x45), QKeyCode "num_lock", number 0x45 +Num_Lock 0x45 + +# evdev 70 (0x46), QKeyCode "scroll_lock", number 0x46 +Scroll_Lock 0x46 + +# evdev 71 (0x47), QKeyCode "kp_7", number 0x47 +KP_Home 0x47 +KP_7 0x47 numlock + +# evdev 72 (0x48), QKeyCode "kp_8", number 0x48 +KP_Up 0x48 +KP_8 0x48 numlock + +# evdev 73 (0x49), QKeyCode "kp_9", number 0x49 +KP_Prior 0x49 +KP_9 0x49 numlock + +# evdev 74 (0x4a), QKeyCode "kp_subtract", number 0x4a +KP_Subtract 0x4a + +# evdev 75 (0x4b), QKeyCode "kp_4", number 0x4b +KP_Left 0x4b +KP_4 0x4b numlock + +# evdev 76 (0x4c), QKeyCode "kp_5", number 0x4c +KP_Begin 0x4c +KP_5 0x4c numlock + +# evdev 77 (0x4d), QKeyCode "kp_6", number 0x4d +KP_Right 0x4d +KP_6 0x4d numlock + +# evdev 78 (0x4e), QKeyCode "kp_add", number 0x4e +KP_Add 0x4e + +# evdev 79 (0x4f), QKeyCode "kp_1", number 0x4f +KP_End 0x4f +KP_1 0x4f numlock + +# evdev 80 (0x50), QKeyCode "kp_2", number 0x50 +KP_Down 0x50 +KP_2 0x50 numlock + +# evdev 81 (0x51), QKeyCode "kp_3", number 0x51 +KP_Next 0x51 +KP_3 0x51 numlock + +# evdev 82 (0x52), QKeyCode "kp_0", number 0x52 +KP_Insert 0x52 +KP_0 0x52 numlock + +# evdev 83 (0x53), QKeyCode "kp_decimal", number 0x53 +KP_Delete 0x53 +KP_Decimal 0x53 numlock + +# evdev 84 (0x54): no evdev -> QKeyCode mapping (xkb keysym ISO_Level3_Shift) + +# evdev 85 (0x55): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 86 (0x56), QKeyCode "less", number 0x56 +endash 0x56 +EuroSign 0x56 shift +bar 0x56 altgr +brokenbar 0x56 shift altgr + +# evdev 87 (0x57), QKeyCode "f11", number 0x57 +F11 0x57 + +# evdev 88 (0x58), QKeyCode "f12", number 0x58 +F12 0x58 + +# evdev 89 (0x59), QKeyCode "ro", number 0x73 + +# evdev 90 (0x5a): no evdev -> QKeyCode mapping (xkb keysym Katakana) + +# evdev 91 (0x5b), QKeyCode "hiragana", number 0x77 +Hiragana 0x77 + +# evdev 92 (0x5c), QKeyCode "henkan", number 0x79 +Henkan_Mode 0x79 + +# evdev 93 (0x5d), QKeyCode "katakanahiragana", number 0x70 +Hiragana_Katakana 0x70 + +# evdev 94 (0x5e), QKeyCode "muhenkan", number 0x7b +Muhenkan 0x7b + +# evdev 95 (0x5f): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 96 (0x60), QKeyCode "kp_enter", number 0x9c +KP_Enter 0x9c + +# evdev 97 (0x61), QKeyCode "ctrl_r", number 0x9d +Control_R 0x9d + +# evdev 98 (0x62), QKeyCode "kp_divide", number 0xb5 +KP_Divide 0xb5 + +# evdev 99 (0x63), QKeyCode "sysrq", number 0x54 +Print 0x54 + +# evdev 100 (0x64), QKeyCode "alt_r", number 0xb8 +ISO_Level3_Shift 0xb8 + +# evdev 101 (0x65), QKeyCode "lf", number 0x5b +Linefeed 0x5b + +# evdev 102 (0x66), QKeyCode "home", number 0xc7 +Home 0xc7 + +# evdev 103 (0x67), QKeyCode "up", number 0xc8 +Up 0xc8 + +# evdev 104 (0x68), QKeyCode "pgup", number 0xc9 +Prior 0xc9 + +# evdev 105 (0x69), QKeyCode "left", number 0xcb +Left 0xcb + +# evdev 106 (0x6a), QKeyCode "right", number 0xcd +Right 0xcd + +# evdev 107 (0x6b), QKeyCode "end", number 0xcf +End 0xcf + +# evdev 108 (0x6c), QKeyCode "down", number 0xd0 +Down 0xd0 + +# evdev 109 (0x6d), QKeyCode "pgdn", number 0xd1 +Next 0xd1 + +# evdev 110 (0x6e), QKeyCode "insert", number 0xd2 +Insert 0xd2 + +# evdev 111 (0x6f), QKeyCode "delete", number 0xd3 +Delete 0xd3 + +# evdev 112 (0x70): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 113 (0x71), QKeyCode "audiomute", number 0xa0 +XF86AudioMute 0xa0 + +# evdev 114 (0x72), QKeyCode "volumedown", number 0xae +XF86AudioLowerVolume 0xae + +# evdev 115 (0x73), QKeyCode "volumeup", number 0xb0 +XF86AudioRaiseVolume 0xb0 + +# evdev 116 (0x74), QKeyCode "power", number 0xde +XF86PowerOff 0xde + +# evdev 117 (0x75), QKeyCode "kp_equals", number 0x59 +KP_Equal 0x59 + +# evdev 118 (0x76): no evdev -> QKeyCode mapping (xkb keysym plusminus) + +# evdev 119 (0x77), QKeyCode "pause", number 0xc6 +Pause 0xc6 + +# evdev 120 (0x78): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchA) + +# evdev 121 (0x79), QKeyCode "kp_comma", number 0x7e +KP_Decimal 0x7e + +# evdev 122 (0x7a): no evdev -> QKeyCode mapping (xkb keysym Hangul) + +# evdev 123 (0x7b): no evdev -> QKeyCode mapping (xkb keysym Hangul_Hanja) + +# evdev 124 (0x7c), QKeyCode "yen", number 0x7d + +# evdev 125 (0x7d), QKeyCode "meta_l", number 0xdb +Super_L 0xdb + +# evdev 126 (0x7e), QKeyCode "meta_r", number 0xdc +Super_R 0xdc + +# evdev 127 (0x7f), QKeyCode "compose", number 0xdd +Menu 0xdd + +# evdev 128 (0x80), QKeyCode "stop", number 0xe8 +Cancel 0xe8 + +# evdev 129 (0x81), QKeyCode "again", number 0x85 +Redo 0x85 + +# evdev 130 (0x82), QKeyCode "props", number 0x86 +SunProps 0x86 + +# evdev 131 (0x83), QKeyCode "undo", number 0x87 +Undo 0x87 + +# evdev 132 (0x84), QKeyCode "front", number 0x8c +SunFront 0x8c + +# evdev 133 (0x85), QKeyCode "copy", number 0xf8 +XF86Copy 0xf8 + +# evdev 134 (0x86), QKeyCode "open", number 0x64 +XF86Open 0x64 + +# evdev 135 (0x87), QKeyCode "paste", number 0x65 +XF86Paste 0x65 + +# evdev 136 (0x88), QKeyCode "find", number 0xc1 +Find 0xc1 + +# evdev 137 (0x89), QKeyCode "cut", number 0xbc +XF86Cut 0xbc + +# evdev 138 (0x8a), QKeyCode "help", number 0xf5 +Help 0xf5 + +# evdev 139 (0x8b), QKeyCode "menu", number 0x9e +XF86MenuKB 0x9e + +# evdev 140 (0x8c), QKeyCode "calculator", number 0xa1 +XF86Calculator 0xa1 + +# evdev 141 (0x8d): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 142 (0x8e), QKeyCode "sleep", number 0xdf +XF86Sleep 0xdf + +# evdev 143 (0x8f), QKeyCode "wake", number 0xe3 +XF86WakeUp 0xe3 + +# evdev 144 (0x90): no evdev -> QKeyCode mapping (xkb keysym XF86Explorer) + +# evdev 145 (0x91): no evdev -> QKeyCode mapping (xkb keysym XF86Send) + +# evdev 146 (0x92): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 147 (0x93): no evdev -> QKeyCode mapping (xkb keysym XF86Xfer) + +# evdev 148 (0x94): no evdev -> QKeyCode mapping (xkb keysym XF86Launch1) + +# evdev 149 (0x95): no evdev -> QKeyCode mapping (xkb keysym XF86Launch2) + +# evdev 150 (0x96): no evdev -> QKeyCode mapping (xkb keysym XF86WWW) + +# evdev 151 (0x97): no evdev -> QKeyCode mapping (xkb keysym XF86DOS) + +# evdev 152 (0x98): no evdev -> QKeyCode mapping (xkb keysym XF86ScreenSaver) + +# evdev 153 (0x99): no evdev -> QKeyCode mapping (xkb keysym XF86RotateWindows) + +# evdev 154 (0x9a): no evdev -> QKeyCode mapping (xkb keysym XF86TaskPane) + +# evdev 155 (0x9b), QKeyCode "mail", number 0xec +XF86Mail 0xec + +# evdev 156 (0x9c), QKeyCode "ac_bookmarks", number 0xe6 +XF86Favorites 0xe6 + +# evdev 157 (0x9d), QKeyCode "computer", number 0xeb +XF86MyComputer 0xeb + +# evdev 158 (0x9e), QKeyCode "ac_back", number 0xea +XF86Back 0xea + +# evdev 159 (0x9f), QKeyCode "ac_forward", number 0xe9 +XF86Forward 0xe9 + +# evdev 160 (0xa0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 161 (0xa1): no evdev -> QKeyCode mapping (xkb keysym XF86Eject) + +# evdev 162 (0xa2): no evdev -> QKeyCode mapping (xkb keysym XF86Eject) + +# evdev 163 (0xa3), QKeyCode "audionext", number 0x99 +XF86AudioNext 0x99 + +# evdev 164 (0xa4), QKeyCode "audioplay", number 0xa2 +XF86AudioPlay 0xa2 +XF86AudioPause 0xa2 shift + +# evdev 165 (0xa5), QKeyCode "audioprev", number 0x90 +XF86AudioPrev 0x90 + +# evdev 166 (0xa6), QKeyCode "audiostop", number 0xa4 +XF86AudioStop 0xa4 +XF86Eject 0xa4 shift + +# evdev 167 (0xa7): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRecord) + +# evdev 168 (0xa8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRewind) + +# evdev 169 (0xa9): no evdev -> QKeyCode mapping (xkb keysym XF86Phone) + +# evdev 170 (0xaa): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 171 (0xab): no evdev -> QKeyCode mapping (xkb keysym XF86Tools) + +# evdev 172 (0xac), QKeyCode "ac_home", number 0xb2 +XF86HomePage 0xb2 + +# evdev 173 (0xad), QKeyCode "ac_refresh", number 0xe7 +XF86Reload 0xe7 + +# evdev 174 (0xae): no evdev -> QKeyCode mapping (xkb keysym XF86Close) + +# evdev 175 (0xaf): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 176 (0xb0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 177 (0xb1): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollUp) + +# evdev 178 (0xb2): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollDown) + +# evdev 179 (0xb3): no evdev -> QKeyCode mapping (xkb keysym parenleft) + +# evdev 180 (0xb4): no evdev -> QKeyCode mapping (xkb keysym parenright) + +# evdev 181 (0xb5): no evdev -> QKeyCode mapping (xkb keysym XF86New) + +# evdev 182 (0xb6): no evdev -> QKeyCode mapping (xkb keysym Redo) + +# evdev 183 (0xb7): no evdev -> QKeyCode mapping (xkb keysym XF86Tools) + +# evdev 184 (0xb8): no evdev -> QKeyCode mapping (xkb keysym XF86Launch5) + +# evdev 185 (0xb9): no evdev -> QKeyCode mapping (xkb keysym XF86Launch6) + +# evdev 186 (0xba): no evdev -> QKeyCode mapping (xkb keysym XF86Launch7) + +# evdev 187 (0xbb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch8) + +# evdev 188 (0xbc): no evdev -> QKeyCode mapping (xkb keysym XF86Launch9) + +# evdev 189 (0xbd): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 190 (0xbe): no evdev -> QKeyCode mapping (xkb keysym XF86AudioMicMute) + +# evdev 191 (0xbf): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadToggle) + +# evdev 192 (0xc0): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOn) + +# evdev 193 (0xc1): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOff) + +# evdev 194 (0xc2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 195 (0xc3): no evdev -> QKeyCode mapping (xkb keysym Mode_switch) + +# evdev 196 (0xc4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 197 (0xc5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 198 (0xc6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 199 (0xc7): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 200 (0xc8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay) + +# evdev 201 (0xc9): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPause) + +# evdev 202 (0xca): no evdev -> QKeyCode mapping (xkb keysym XF86Launch3) + +# evdev 203 (0xcb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch4) + +# evdev 204 (0xcc): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchB) + +# evdev 205 (0xcd): no evdev -> QKeyCode mapping (xkb keysym XF86Suspend) + +# evdev 206 (0xce): no evdev -> QKeyCode mapping (xkb keysym XF86Close) + +# evdev 207 (0xcf): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay) + +# evdev 208 (0xd0): no evdev -> QKeyCode mapping (xkb keysym XF86AudioForward) + +# evdev 209 (0xd1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 210 (0xd2): no evdev -> QKeyCode mapping (xkb keysym Print) + +# evdev 211 (0xd3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 212 (0xd4): no evdev -> QKeyCode mapping (xkb keysym XF86WebCam) + +# evdev 213 (0xd5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 214 (0xd6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 215 (0xd7): no evdev -> QKeyCode mapping (xkb keysym XF86Mail) + +# evdev 216 (0xd8): no evdev -> QKeyCode mapping (xkb keysym XF86Messenger) + +# evdev 217 (0xd9): no evdev -> QKeyCode mapping (xkb keysym XF86Search) + +# evdev 218 (0xda): no evdev -> QKeyCode mapping (xkb keysym XF86Go) + +# evdev 219 (0xdb): no evdev -> QKeyCode mapping (xkb keysym XF86Finance) + +# evdev 220 (0xdc): no evdev -> QKeyCode mapping (xkb keysym XF86Game) + +# evdev 221 (0xdd): no evdev -> QKeyCode mapping (xkb keysym XF86Shop) + +# evdev 222 (0xde): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 223 (0xdf): no evdev -> QKeyCode mapping (xkb keysym Cancel) + +# evdev 224 (0xe0): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessDown) + +# evdev 225 (0xe1): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessUp) + +# evdev 226 (0xe2), QKeyCode "mediaselect", number 0xed +XF86AudioMedia 0xed + +# evdev 227 (0xe3): no evdev -> QKeyCode mapping (xkb keysym XF86Display) + +# evdev 228 (0xe4): no evdev -> QKeyCode mapping (xkb keysym XF86KbdLightOnOff) + +# evdev 229 (0xe5): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessDown) + +# evdev 230 (0xe6): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessUp) + +# evdev 231 (0xe7): no evdev -> QKeyCode mapping (xkb keysym XF86Send) + +# evdev 232 (0xe8): no evdev -> QKeyCode mapping (xkb keysym XF86Reply) + +# evdev 233 (0xe9): no evdev -> QKeyCode mapping (xkb keysym XF86MailForward) + +# evdev 234 (0xea): no evdev -> QKeyCode mapping (xkb keysym XF86Save) + +# evdev 235 (0xeb): no evdev -> QKeyCode mapping (xkb keysym XF86Documents) + +# evdev 236 (0xec): no evdev -> QKeyCode mapping (xkb keysym XF86Battery) + +# evdev 237 (0xed): no evdev -> QKeyCode mapping (xkb keysym XF86Bluetooth) + +# evdev 238 (0xee): no evdev -> QKeyCode mapping (xkb keysym XF86WLAN) + +# evdev 239 (0xef): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 240 (0xf0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 241 (0xf1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 242 (0xf2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 243 (0xf3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 244 (0xf4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 245 (0xf5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 246 (0xf6): no evdev -> QKeyCode mapping (xkb keysym Invalid) + +# evdev 247 (0xf7): no evdev -> QKeyCode mapping (xkb keysym Invalid) + +# +# quirks section start +# +# Sometimes multiple keysyms map to the same keycodes. +# The keycode -> keysym lookup finds only one of the +# keysyms. So append them here. +# + +Print 0x54 +Sys_Req 0x54 +Execute 0x54 +KP_Decimal 0x53 numlock +KP_Separator 0x53 numlock +Alt_R 0xb8 +ISO_Level3_Shift 0xb8 +Mode_switch 0xb8 + +# quirks section end diff --git a/app/src/main/assets/roms/keymaps/lv b/app/src/main/assets/roms/keymaps/lv new file mode 100644 index 0000000..54997ce --- /dev/null +++ b/app/src/main/assets/roms/keymaps/lv @@ -0,0 +1,816 @@ +# +# generated by qemu-keymap +# model : pc105 +# layout : lv +# variant : - +# options : - + +# name: "Latvian" + +# modifiers +# 0: Shift +# 1: Lock +# 2: Control +# 3: Mod1 +# 4: Mod2 +# 5: Mod3 +# 6: Mod4 +# 7: Mod5 +# 8: NumLock +# 9: Alt +# 10: LevelThree +# 11: LAlt +# 12: RAlt +# 13: RControl +# 14: LControl +# 15: ScrollLock +# 16: LevelFive +# 17: AltGr +# 18: Meta +# 19: Super +# 20: Hyper + +# evdev 1 (0x1), QKeyCode "esc", number 0x1 +Escape 0x01 + +# evdev 2 (0x2), QKeyCode "1", number 0x2 +1 0x02 +exclam 0x02 shift +onesuperior 0x02 altgr +exclamdown 0x02 shift altgr + +# evdev 3 (0x3), QKeyCode "2", number 0x3 +2 0x03 +at 0x03 shift +twosuperior 0x03 altgr +oneeighth 0x03 shift altgr + +# evdev 4 (0x4), QKeyCode "3", number 0x4 +3 0x04 +numbersign 0x04 shift +threesuperior 0x04 altgr +sterling 0x04 shift altgr + +# evdev 5 (0x5), QKeyCode "4", number 0x5 +4 0x05 +dollar 0x05 shift +EuroSign 0x05 altgr +cent 0x05 shift altgr + +# evdev 6 (0x6), QKeyCode "5", number 0x6 +5 0x06 +percent 0x06 shift +onehalf 0x06 altgr +threeeighths 0x06 shift altgr + +# evdev 7 (0x7), QKeyCode "6", number 0x7 +6 0x07 +asciicircum 0x07 shift +threequarters 0x07 altgr +fiveeighths 0x07 shift altgr + +# evdev 8 (0x8), QKeyCode "7", number 0x8 +7 0x08 +ampersand 0x08 shift +braceleft 0x08 altgr +seveneighths 0x08 shift altgr + +# evdev 9 (0x9), QKeyCode "8", number 0x9 +8 0x09 +asterisk 0x09 shift +bracketleft 0x09 altgr +trademark 0x09 shift altgr + +# evdev 10 (0xa), QKeyCode "9", number 0xa +9 0x0a +parenleft 0x0a shift +bracketright 0x0a altgr +plusminus 0x0a shift altgr + +# evdev 11 (0xb), QKeyCode "0", number 0xb +0 0x0b +parenright 0x0b shift +braceright 0x0b altgr +degree 0x0b shift altgr + +# evdev 12 (0xc), QKeyCode "minus", number 0xc +minus 0x0c +underscore 0x0c shift +backslash 0x0c altgr +questiondown 0x0c shift altgr + +# evdev 13 (0xd), QKeyCode "equal", number 0xd +equal 0x0d +plus 0x0d shift +endash 0x0d altgr +emdash 0x0d shift altgr + +# evdev 14 (0xe), QKeyCode "backspace", number 0xe +BackSpace 0x0e + +# evdev 15 (0xf), QKeyCode "tab", number 0xf +Tab 0x0f +ISO_Left_Tab 0x0f shift + +# evdev 16 (0x10), QKeyCode "q", number 0x10 +q 0x10 +Q 0x10 shift + +# evdev 17 (0x11), QKeyCode "w", number 0x11 +w 0x11 +W 0x11 shift + +# evdev 18 (0x12), QKeyCode "e", number 0x12 +e 0x12 +E 0x12 shift +emacron 0x12 altgr +Emacron 0x12 shift altgr + +# evdev 19 (0x13), QKeyCode "r", number 0x13 +r 0x13 +R 0x13 shift +rcedilla 0x13 altgr +Rcedilla 0x13 shift altgr + +# evdev 20 (0x14), QKeyCode "t", number 0x14 +t 0x14 +T 0x14 shift + +# evdev 21 (0x15), QKeyCode "y", number 0x15 +y 0x15 +Y 0x15 shift + +# evdev 22 (0x16), QKeyCode "u", number 0x16 +u 0x16 +U 0x16 shift +umacron 0x16 altgr +Umacron 0x16 shift altgr + +# evdev 23 (0x17), QKeyCode "i", number 0x17 +i 0x17 +I 0x17 shift +imacron 0x17 altgr +Imacron 0x17 shift altgr + +# evdev 24 (0x18), QKeyCode "o", number 0x18 +o 0x18 +O 0x18 shift +omacron 0x18 altgr +Omacron 0x18 shift altgr + +# evdev 25 (0x19), QKeyCode "p", number 0x19 +p 0x19 +P 0x19 shift + +# evdev 26 (0x1a), QKeyCode "bracket_left", number 0x1a +bracketleft 0x1a +braceleft 0x1a shift +guillemotleft 0x1a altgr +leftdoublequotemark 0x1a shift altgr + +# evdev 27 (0x1b), QKeyCode "bracket_right", number 0x1b +bracketright 0x1b +braceright 0x1b shift +guillemotright 0x1b altgr +rightdoublequotemark 0x1b shift altgr + +# evdev 28 (0x1c), QKeyCode "ret", number 0x1c +Return 0x1c + +# evdev 29 (0x1d), QKeyCode "ctrl", number 0x1d +Control_L 0x1d + +# evdev 30 (0x1e), QKeyCode "a", number 0x1e +a 0x1e +A 0x1e shift +amacron 0x1e altgr +Amacron 0x1e shift altgr + +# evdev 31 (0x1f), QKeyCode "s", number 0x1f +s 0x1f +S 0x1f shift +scaron 0x1f altgr +Scaron 0x1f shift altgr + +# evdev 32 (0x20), QKeyCode "d", number 0x20 +d 0x20 +D 0x20 shift + +# evdev 33 (0x21), QKeyCode "f", number 0x21 +f 0x21 +F 0x21 shift + +# evdev 34 (0x22), QKeyCode "g", number 0x22 +g 0x22 +G 0x22 shift +gcedilla 0x22 altgr +Gcedilla 0x22 shift altgr + +# evdev 35 (0x23), QKeyCode "h", number 0x23 +h 0x23 +H 0x23 shift + +# evdev 36 (0x24), QKeyCode "j", number 0x24 +j 0x24 +J 0x24 shift + +# evdev 37 (0x25), QKeyCode "k", number 0x25 +k 0x25 +K 0x25 shift +kcedilla 0x25 altgr +Kcedilla 0x25 shift altgr + +# evdev 38 (0x26), QKeyCode "l", number 0x26 +l 0x26 +L 0x26 shift +lcedilla 0x26 altgr +Lcedilla 0x26 shift altgr + +# evdev 39 (0x27), QKeyCode "semicolon", number 0x27 +semicolon 0x27 +colon 0x27 shift + +# evdev 40 (0x28), QKeyCode "apostrophe", number 0x28 +apostrophe 0x28 +quotedbl 0x28 shift +leftdoublequotemark 0x28 altgr +doublelowquotemark 0x28 shift altgr + +# evdev 41 (0x29), QKeyCode "grave_accent", number 0x29 +grave 0x29 +asciitilde 0x29 shift +acute 0x29 altgr + +# evdev 42 (0x2a), QKeyCode "shift", number 0x2a +Shift_L 0x2a + +# evdev 43 (0x2b), QKeyCode "backslash", number 0x2b +backslash 0x2b +bar 0x2b shift +grave 0x2b altgr +breve 0x2b shift altgr + +# evdev 44 (0x2c), QKeyCode "z", number 0x2c +z 0x2c +Z 0x2c shift +zcaron 0x2c altgr +Zcaron 0x2c shift altgr + +# evdev 45 (0x2d), QKeyCode "x", number 0x2d +x 0x2d +X 0x2d shift + +# evdev 46 (0x2e), QKeyCode "c", number 0x2e +c 0x2e +C 0x2e shift +ccaron 0x2e altgr +Ccaron 0x2e shift altgr + +# evdev 47 (0x2f), QKeyCode "v", number 0x2f +v 0x2f +V 0x2f shift + +# evdev 48 (0x30), QKeyCode "b", number 0x30 +b 0x30 +B 0x30 shift + +# evdev 49 (0x31), QKeyCode "n", number 0x31 +n 0x31 +N 0x31 shift +ncedilla 0x31 altgr +Ncedilla 0x31 shift altgr + +# evdev 50 (0x32), QKeyCode "m", number 0x32 +m 0x32 +M 0x32 shift + +# evdev 51 (0x33), QKeyCode "comma", number 0x33 +comma 0x33 +less 0x33 shift +horizconnector 0x33 altgr +multiply 0x33 shift altgr + +# evdev 52 (0x34), QKeyCode "dot", number 0x34 +period 0x34 +greater 0x34 shift +periodcentered 0x34 altgr +division 0x34 shift altgr + +# evdev 53 (0x35), QKeyCode "slash", number 0x35 +slash 0x35 +question 0x35 shift +abovedot 0x35 shift altgr + +# evdev 54 (0x36), QKeyCode "shift_r", number 0x36 +Shift_R 0x36 + +# evdev 55 (0x37), QKeyCode "kp_multiply", number 0x37 +KP_Multiply 0x37 + +# evdev 56 (0x38), QKeyCode "alt", number 0x38 +Alt_L 0x38 +Meta_L 0x38 shift + +# evdev 57 (0x39), QKeyCode "spc", number 0x39 +space 0x39 + +# evdev 58 (0x3a), QKeyCode "caps_lock", number 0x3a +Caps_Lock 0x3a + +# evdev 59 (0x3b), QKeyCode "f1", number 0x3b +F1 0x3b + +# evdev 60 (0x3c), QKeyCode "f2", number 0x3c +F2 0x3c + +# evdev 61 (0x3d), QKeyCode "f3", number 0x3d +F3 0x3d + +# evdev 62 (0x3e), QKeyCode "f4", number 0x3e +F4 0x3e + +# evdev 63 (0x3f), QKeyCode "f5", number 0x3f +F5 0x3f + +# evdev 64 (0x40), QKeyCode "f6", number 0x40 +F6 0x40 + +# evdev 65 (0x41), QKeyCode "f7", number 0x41 +F7 0x41 + +# evdev 66 (0x42), QKeyCode "f8", number 0x42 +F8 0x42 + +# evdev 67 (0x43), QKeyCode "f9", number 0x43 +F9 0x43 + +# evdev 68 (0x44), QKeyCode "f10", number 0x44 +F10 0x44 + +# evdev 69 (0x45), QKeyCode "num_lock", number 0x45 +Num_Lock 0x45 + +# evdev 70 (0x46), QKeyCode "scroll_lock", number 0x46 +Scroll_Lock 0x46 + +# evdev 71 (0x47), QKeyCode "kp_7", number 0x47 +KP_Home 0x47 +KP_7 0x47 numlock + +# evdev 72 (0x48), QKeyCode "kp_8", number 0x48 +KP_Up 0x48 +KP_8 0x48 numlock + +# evdev 73 (0x49), QKeyCode "kp_9", number 0x49 +KP_Prior 0x49 +KP_9 0x49 numlock + +# evdev 74 (0x4a), QKeyCode "kp_subtract", number 0x4a +KP_Subtract 0x4a + +# evdev 75 (0x4b), QKeyCode "kp_4", number 0x4b +KP_Left 0x4b +KP_4 0x4b numlock + +# evdev 76 (0x4c), QKeyCode "kp_5", number 0x4c +KP_Begin 0x4c +KP_5 0x4c numlock + +# evdev 77 (0x4d), QKeyCode "kp_6", number 0x4d +KP_Right 0x4d +KP_6 0x4d numlock + +# evdev 78 (0x4e), QKeyCode "kp_add", number 0x4e +KP_Add 0x4e + +# evdev 79 (0x4f), QKeyCode "kp_1", number 0x4f +KP_End 0x4f +KP_1 0x4f numlock + +# evdev 80 (0x50), QKeyCode "kp_2", number 0x50 +KP_Down 0x50 +KP_2 0x50 numlock + +# evdev 81 (0x51), QKeyCode "kp_3", number 0x51 +KP_Next 0x51 +KP_3 0x51 numlock + +# evdev 82 (0x52), QKeyCode "kp_0", number 0x52 +KP_Insert 0x52 +KP_0 0x52 numlock + +# evdev 83 (0x53), QKeyCode "kp_decimal", number 0x53 +KP_Delete 0x53 +KP_Decimal 0x53 numlock + +# evdev 84 (0x54): no evdev -> QKeyCode mapping (xkb keysym ISO_Level3_Shift) + +# evdev 85 (0x55): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 86 (0x56), QKeyCode "less", number 0x56 +less 0x56 +greater 0x56 shift +bar 0x56 altgr +brokenbar 0x56 shift altgr + +# evdev 87 (0x57), QKeyCode "f11", number 0x57 +F11 0x57 + +# evdev 88 (0x58), QKeyCode "f12", number 0x58 +F12 0x58 + +# evdev 89 (0x59), QKeyCode "ro", number 0x73 + +# evdev 90 (0x5a): no evdev -> QKeyCode mapping (xkb keysym Katakana) + +# evdev 91 (0x5b), QKeyCode "hiragana", number 0x77 +Hiragana 0x77 + +# evdev 92 (0x5c), QKeyCode "henkan", number 0x79 +Henkan_Mode 0x79 + +# evdev 93 (0x5d), QKeyCode "katakanahiragana", number 0x70 +Hiragana_Katakana 0x70 + +# evdev 94 (0x5e), QKeyCode "muhenkan", number 0x7b +Muhenkan 0x7b + +# evdev 95 (0x5f): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 96 (0x60), QKeyCode "kp_enter", number 0x9c +KP_Enter 0x9c + +# evdev 97 (0x61), QKeyCode "ctrl_r", number 0x9d +Control_R 0x9d + +# evdev 98 (0x62), QKeyCode "kp_divide", number 0xb5 +KP_Divide 0xb5 + +# evdev 99 (0x63), QKeyCode "sysrq", number 0x54 +Print 0x54 + +# evdev 100 (0x64), QKeyCode "alt_r", number 0xb8 +ISO_Level3_Shift 0xb8 + +# evdev 101 (0x65), QKeyCode "lf", number 0x5b +Linefeed 0x5b + +# evdev 102 (0x66), QKeyCode "home", number 0xc7 +Home 0xc7 + +# evdev 103 (0x67), QKeyCode "up", number 0xc8 +Up 0xc8 + +# evdev 104 (0x68), QKeyCode "pgup", number 0xc9 +Prior 0xc9 + +# evdev 105 (0x69), QKeyCode "left", number 0xcb +Left 0xcb + +# evdev 106 (0x6a), QKeyCode "right", number 0xcd +Right 0xcd + +# evdev 107 (0x6b), QKeyCode "end", number 0xcf +End 0xcf + +# evdev 108 (0x6c), QKeyCode "down", number 0xd0 +Down 0xd0 + +# evdev 109 (0x6d), QKeyCode "pgdn", number 0xd1 +Next 0xd1 + +# evdev 110 (0x6e), QKeyCode "insert", number 0xd2 +Insert 0xd2 + +# evdev 111 (0x6f), QKeyCode "delete", number 0xd3 +Delete 0xd3 + +# evdev 112 (0x70): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 113 (0x71), QKeyCode "audiomute", number 0xa0 +XF86AudioMute 0xa0 + +# evdev 114 (0x72), QKeyCode "volumedown", number 0xae +XF86AudioLowerVolume 0xae + +# evdev 115 (0x73), QKeyCode "volumeup", number 0xb0 +XF86AudioRaiseVolume 0xb0 + +# evdev 116 (0x74), QKeyCode "power", number 0xde +XF86PowerOff 0xde + +# evdev 117 (0x75), QKeyCode "kp_equals", number 0x59 +KP_Equal 0x59 + +# evdev 118 (0x76): no evdev -> QKeyCode mapping (xkb keysym plusminus) + +# evdev 119 (0x77), QKeyCode "pause", number 0xc6 +Pause 0xc6 + +# evdev 120 (0x78): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchA) + +# evdev 121 (0x79), QKeyCode "kp_comma", number 0x7e +KP_Decimal 0x7e + +# evdev 122 (0x7a): no evdev -> QKeyCode mapping (xkb keysym Hangul) + +# evdev 123 (0x7b): no evdev -> QKeyCode mapping (xkb keysym Hangul_Hanja) + +# evdev 124 (0x7c), QKeyCode "yen", number 0x7d + +# evdev 125 (0x7d), QKeyCode "meta_l", number 0xdb +Super_L 0xdb + +# evdev 126 (0x7e), QKeyCode "meta_r", number 0xdc +Super_R 0xdc + +# evdev 127 (0x7f), QKeyCode "compose", number 0xdd +Menu 0xdd + +# evdev 128 (0x80), QKeyCode "stop", number 0xe8 +Cancel 0xe8 + +# evdev 129 (0x81), QKeyCode "again", number 0x85 +Redo 0x85 + +# evdev 130 (0x82), QKeyCode "props", number 0x86 +SunProps 0x86 + +# evdev 131 (0x83), QKeyCode "undo", number 0x87 +Undo 0x87 + +# evdev 132 (0x84), QKeyCode "front", number 0x8c +SunFront 0x8c + +# evdev 133 (0x85), QKeyCode "copy", number 0xf8 +XF86Copy 0xf8 + +# evdev 134 (0x86), QKeyCode "open", number 0x64 +XF86Open 0x64 + +# evdev 135 (0x87), QKeyCode "paste", number 0x65 +XF86Paste 0x65 + +# evdev 136 (0x88), QKeyCode "find", number 0xc1 +Find 0xc1 + +# evdev 137 (0x89), QKeyCode "cut", number 0xbc +XF86Cut 0xbc + +# evdev 138 (0x8a), QKeyCode "help", number 0xf5 +Help 0xf5 + +# evdev 139 (0x8b), QKeyCode "menu", number 0x9e +XF86MenuKB 0x9e + +# evdev 140 (0x8c), QKeyCode "calculator", number 0xa1 +XF86Calculator 0xa1 + +# evdev 141 (0x8d): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 142 (0x8e), QKeyCode "sleep", number 0xdf +XF86Sleep 0xdf + +# evdev 143 (0x8f), QKeyCode "wake", number 0xe3 +XF86WakeUp 0xe3 + +# evdev 144 (0x90): no evdev -> QKeyCode mapping (xkb keysym XF86Explorer) + +# evdev 145 (0x91): no evdev -> QKeyCode mapping (xkb keysym XF86Send) + +# evdev 146 (0x92): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 147 (0x93): no evdev -> QKeyCode mapping (xkb keysym XF86Xfer) + +# evdev 148 (0x94): no evdev -> QKeyCode mapping (xkb keysym XF86Launch1) + +# evdev 149 (0x95): no evdev -> QKeyCode mapping (xkb keysym XF86Launch2) + +# evdev 150 (0x96): no evdev -> QKeyCode mapping (xkb keysym XF86WWW) + +# evdev 151 (0x97): no evdev -> QKeyCode mapping (xkb keysym XF86DOS) + +# evdev 152 (0x98): no evdev -> QKeyCode mapping (xkb keysym XF86ScreenSaver) + +# evdev 153 (0x99): no evdev -> QKeyCode mapping (xkb keysym XF86RotateWindows) + +# evdev 154 (0x9a): no evdev -> QKeyCode mapping (xkb keysym XF86TaskPane) + +# evdev 155 (0x9b), QKeyCode "mail", number 0xec +XF86Mail 0xec + +# evdev 156 (0x9c), QKeyCode "ac_bookmarks", number 0xe6 +XF86Favorites 0xe6 + +# evdev 157 (0x9d), QKeyCode "computer", number 0xeb +XF86MyComputer 0xeb + +# evdev 158 (0x9e), QKeyCode "ac_back", number 0xea +XF86Back 0xea + +# evdev 159 (0x9f), QKeyCode "ac_forward", number 0xe9 +XF86Forward 0xe9 + +# evdev 160 (0xa0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 161 (0xa1): no evdev -> QKeyCode mapping (xkb keysym XF86Eject) + +# evdev 162 (0xa2): no evdev -> QKeyCode mapping (xkb keysym XF86Eject) + +# evdev 163 (0xa3), QKeyCode "audionext", number 0x99 +XF86AudioNext 0x99 + +# evdev 164 (0xa4), QKeyCode "audioplay", number 0xa2 +XF86AudioPlay 0xa2 +XF86AudioPause 0xa2 shift + +# evdev 165 (0xa5), QKeyCode "audioprev", number 0x90 +XF86AudioPrev 0x90 + +# evdev 166 (0xa6), QKeyCode "audiostop", number 0xa4 +XF86AudioStop 0xa4 +XF86Eject 0xa4 shift + +# evdev 167 (0xa7): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRecord) + +# evdev 168 (0xa8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRewind) + +# evdev 169 (0xa9): no evdev -> QKeyCode mapping (xkb keysym XF86Phone) + +# evdev 170 (0xaa): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 171 (0xab): no evdev -> QKeyCode mapping (xkb keysym XF86Tools) + +# evdev 172 (0xac), QKeyCode "ac_home", number 0xb2 +XF86HomePage 0xb2 + +# evdev 173 (0xad), QKeyCode "ac_refresh", number 0xe7 +XF86Reload 0xe7 + +# evdev 174 (0xae): no evdev -> QKeyCode mapping (xkb keysym XF86Close) + +# evdev 175 (0xaf): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 176 (0xb0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 177 (0xb1): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollUp) + +# evdev 178 (0xb2): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollDown) + +# evdev 179 (0xb3): no evdev -> QKeyCode mapping (xkb keysym parenleft) + +# evdev 180 (0xb4): no evdev -> QKeyCode mapping (xkb keysym parenright) + +# evdev 181 (0xb5): no evdev -> QKeyCode mapping (xkb keysym XF86New) + +# evdev 182 (0xb6): no evdev -> QKeyCode mapping (xkb keysym Redo) + +# evdev 183 (0xb7): no evdev -> QKeyCode mapping (xkb keysym XF86Tools) + +# evdev 184 (0xb8): no evdev -> QKeyCode mapping (xkb keysym XF86Launch5) + +# evdev 185 (0xb9): no evdev -> QKeyCode mapping (xkb keysym XF86Launch6) + +# evdev 186 (0xba): no evdev -> QKeyCode mapping (xkb keysym XF86Launch7) + +# evdev 187 (0xbb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch8) + +# evdev 188 (0xbc): no evdev -> QKeyCode mapping (xkb keysym XF86Launch9) + +# evdev 189 (0xbd): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 190 (0xbe): no evdev -> QKeyCode mapping (xkb keysym XF86AudioMicMute) + +# evdev 191 (0xbf): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadToggle) + +# evdev 192 (0xc0): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOn) + +# evdev 193 (0xc1): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOff) + +# evdev 194 (0xc2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 195 (0xc3): no evdev -> QKeyCode mapping (xkb keysym Mode_switch) + +# evdev 196 (0xc4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 197 (0xc5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 198 (0xc6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 199 (0xc7): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 200 (0xc8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay) + +# evdev 201 (0xc9): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPause) + +# evdev 202 (0xca): no evdev -> QKeyCode mapping (xkb keysym XF86Launch3) + +# evdev 203 (0xcb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch4) + +# evdev 204 (0xcc): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchB) + +# evdev 205 (0xcd): no evdev -> QKeyCode mapping (xkb keysym XF86Suspend) + +# evdev 206 (0xce): no evdev -> QKeyCode mapping (xkb keysym XF86Close) + +# evdev 207 (0xcf): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay) + +# evdev 208 (0xd0): no evdev -> QKeyCode mapping (xkb keysym XF86AudioForward) + +# evdev 209 (0xd1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 210 (0xd2): no evdev -> QKeyCode mapping (xkb keysym Print) + +# evdev 211 (0xd3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 212 (0xd4): no evdev -> QKeyCode mapping (xkb keysym XF86WebCam) + +# evdev 213 (0xd5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 214 (0xd6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 215 (0xd7): no evdev -> QKeyCode mapping (xkb keysym XF86Mail) + +# evdev 216 (0xd8): no evdev -> QKeyCode mapping (xkb keysym XF86Messenger) + +# evdev 217 (0xd9): no evdev -> QKeyCode mapping (xkb keysym XF86Search) + +# evdev 218 (0xda): no evdev -> QKeyCode mapping (xkb keysym XF86Go) + +# evdev 219 (0xdb): no evdev -> QKeyCode mapping (xkb keysym XF86Finance) + +# evdev 220 (0xdc): no evdev -> QKeyCode mapping (xkb keysym XF86Game) + +# evdev 221 (0xdd): no evdev -> QKeyCode mapping (xkb keysym XF86Shop) + +# evdev 222 (0xde): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 223 (0xdf): no evdev -> QKeyCode mapping (xkb keysym Cancel) + +# evdev 224 (0xe0): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessDown) + +# evdev 225 (0xe1): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessUp) + +# evdev 226 (0xe2), QKeyCode "mediaselect", number 0xed +XF86AudioMedia 0xed + +# evdev 227 (0xe3): no evdev -> QKeyCode mapping (xkb keysym XF86Display) + +# evdev 228 (0xe4): no evdev -> QKeyCode mapping (xkb keysym XF86KbdLightOnOff) + +# evdev 229 (0xe5): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessDown) + +# evdev 230 (0xe6): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessUp) + +# evdev 231 (0xe7): no evdev -> QKeyCode mapping (xkb keysym XF86Send) + +# evdev 232 (0xe8): no evdev -> QKeyCode mapping (xkb keysym XF86Reply) + +# evdev 233 (0xe9): no evdev -> QKeyCode mapping (xkb keysym XF86MailForward) + +# evdev 234 (0xea): no evdev -> QKeyCode mapping (xkb keysym XF86Save) + +# evdev 235 (0xeb): no evdev -> QKeyCode mapping (xkb keysym XF86Documents) + +# evdev 236 (0xec): no evdev -> QKeyCode mapping (xkb keysym XF86Battery) + +# evdev 237 (0xed): no evdev -> QKeyCode mapping (xkb keysym XF86Bluetooth) + +# evdev 238 (0xee): no evdev -> QKeyCode mapping (xkb keysym XF86WLAN) + +# evdev 239 (0xef): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 240 (0xf0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 241 (0xf1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 242 (0xf2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 243 (0xf3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 244 (0xf4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 245 (0xf5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 246 (0xf6): no evdev -> QKeyCode mapping (xkb keysym Invalid) + +# evdev 247 (0xf7): no evdev -> QKeyCode mapping (xkb keysym Invalid) + +# +# quirks section start +# +# Sometimes multiple keysyms map to the same keycodes. +# The keycode -> keysym lookup finds only one of the +# keysyms. So append them here. +# + +Print 0x54 +Sys_Req 0x54 +Execute 0x54 +KP_Decimal 0x53 numlock +KP_Separator 0x53 numlock +Alt_R 0xb8 +ISO_Level3_Shift 0xb8 +Mode_switch 0xb8 + +# quirks section end diff --git a/app/src/main/assets/roms/keymaps/mk b/app/src/main/assets/roms/keymaps/mk new file mode 100644 index 0000000..cb362b6 --- /dev/null +++ b/app/src/main/assets/roms/keymaps/mk @@ -0,0 +1,753 @@ +# +# generated by qemu-keymap +# model : pc105 +# layout : mk +# variant : - +# options : - + +# name: "Macedonian" + +# modifiers +# 0: Shift +# 1: Lock +# 2: Control +# 3: Mod1 +# 4: Mod2 +# 5: Mod3 +# 6: Mod4 +# 7: Mod5 +# 8: NumLock +# 9: Alt +# 10: LevelThree +# 11: LAlt +# 12: RAlt +# 13: RControl +# 14: LControl +# 15: ScrollLock +# 16: LevelFive +# 17: AltGr +# 18: Meta +# 19: Super +# 20: Hyper + +# evdev 1 (0x1), QKeyCode "esc", number 0x1 +Escape 0x01 + +# evdev 2 (0x2), QKeyCode "1", number 0x2 +1 0x02 +exclam 0x02 shift + +# evdev 3 (0x3), QKeyCode "2", number 0x3 +2 0x03 +doublelowquotemark 0x03 shift + +# evdev 4 (0x4), QKeyCode "3", number 0x4 +3 0x04 +leftdoublequotemark 0x04 shift + +# evdev 5 (0x5), QKeyCode "4", number 0x5 +4 0x05 +dollar 0x05 shift + +# evdev 6 (0x6), QKeyCode "5", number 0x6 +5 0x06 +percent 0x06 shift + +# evdev 7 (0x7), QKeyCode "6", number 0x7 +6 0x07 +asciicircum 0x07 shift + +# evdev 8 (0x8), QKeyCode "7", number 0x8 +7 0x08 +ampersand 0x08 shift + +# evdev 9 (0x9), QKeyCode "8", number 0x9 +8 0x09 +asterisk 0x09 shift + +# evdev 10 (0xa), QKeyCode "9", number 0xa +9 0x0a +parenleft 0x0a shift + +# evdev 11 (0xb), QKeyCode "0", number 0xb +0 0x0b +parenright 0x0b shift + +# evdev 12 (0xc), QKeyCode "minus", number 0xc +minus 0x0c +underscore 0x0c shift + +# evdev 13 (0xd), QKeyCode "equal", number 0xd +equal 0x0d +plus 0x0d shift + +# evdev 14 (0xe), QKeyCode "backspace", number 0xe +BackSpace 0x0e + +# evdev 15 (0xf), QKeyCode "tab", number 0xf +Tab 0x0f +ISO_Left_Tab 0x0f shift + +# evdev 16 (0x10), QKeyCode "q", number 0x10 +Cyrillic_lje 0x10 +Cyrillic_LJE 0x10 shift + +# evdev 17 (0x11), QKeyCode "w", number 0x11 +Cyrillic_nje 0x11 +Cyrillic_NJE 0x11 shift + +# evdev 18 (0x12), QKeyCode "e", number 0x12 +Cyrillic_ie 0x12 +Cyrillic_IE 0x12 shift + +# evdev 19 (0x13), QKeyCode "r", number 0x13 +Cyrillic_er 0x13 +Cyrillic_ER 0x13 shift + +# evdev 20 (0x14), QKeyCode "t", number 0x14 +Cyrillic_te 0x14 +Cyrillic_TE 0x14 shift + +# evdev 21 (0x15), QKeyCode "y", number 0x15 +Macedonia_dse 0x15 +Macedonia_DSE 0x15 shift + +# evdev 22 (0x16), QKeyCode "u", number 0x16 +Cyrillic_u 0x16 +Cyrillic_U 0x16 shift + +# evdev 23 (0x17), QKeyCode "i", number 0x17 +Cyrillic_i 0x17 +Cyrillic_I 0x17 shift + +# evdev 24 (0x18), QKeyCode "o", number 0x18 +Cyrillic_o 0x18 +Cyrillic_O 0x18 shift + +# evdev 25 (0x19), QKeyCode "p", number 0x19 +Cyrillic_pe 0x19 +Cyrillic_PE 0x19 shift + +# evdev 26 (0x1a), QKeyCode "bracket_left", number 0x1a +Cyrillic_sha 0x1a +Cyrillic_SHA 0x1a shift + +# evdev 27 (0x1b), QKeyCode "bracket_right", number 0x1b +Macedonia_gje 0x1b +Macedonia_GJE 0x1b shift + +# evdev 28 (0x1c), QKeyCode "ret", number 0x1c +Return 0x1c + +# evdev 29 (0x1d), QKeyCode "ctrl", number 0x1d +Control_L 0x1d + +# evdev 30 (0x1e), QKeyCode "a", number 0x1e +Cyrillic_a 0x1e +Cyrillic_A 0x1e shift + +# evdev 31 (0x1f), QKeyCode "s", number 0x1f +Cyrillic_es 0x1f +Cyrillic_ES 0x1f shift + +# evdev 32 (0x20), QKeyCode "d", number 0x20 +Cyrillic_de 0x20 +Cyrillic_DE 0x20 shift + +# evdev 33 (0x21), QKeyCode "f", number 0x21 +Cyrillic_ef 0x21 +Cyrillic_EF 0x21 shift + +# evdev 34 (0x22), QKeyCode "g", number 0x22 +Cyrillic_ghe 0x22 +Cyrillic_GHE 0x22 shift + +# evdev 35 (0x23), QKeyCode "h", number 0x23 +Cyrillic_ha 0x23 +Cyrillic_HA 0x23 shift + +# evdev 36 (0x24), QKeyCode "j", number 0x24 +Cyrillic_je 0x24 +Cyrillic_JE 0x24 shift + +# evdev 37 (0x25), QKeyCode "k", number 0x25 +Cyrillic_ka 0x25 +Cyrillic_KA 0x25 shift + +# evdev 38 (0x26), QKeyCode "l", number 0x26 +Cyrillic_el 0x26 +Cyrillic_EL 0x26 shift + +# evdev 39 (0x27), QKeyCode "semicolon", number 0x27 +Cyrillic_che 0x27 +Cyrillic_CHE 0x27 shift + +# evdev 40 (0x28), QKeyCode "apostrophe", number 0x28 +Macedonia_kje 0x28 +Macedonia_KJE 0x28 shift + +# evdev 41 (0x29), QKeyCode "grave_accent", number 0x29 +dead_grave 0x29 +asciitilde 0x29 shift + +# evdev 42 (0x2a), QKeyCode "shift", number 0x2a +Shift_L 0x2a + +# evdev 43 (0x2b), QKeyCode "backslash", number 0x2b +Cyrillic_zhe 0x2b +Cyrillic_ZHE 0x2b shift + +# evdev 44 (0x2c), QKeyCode "z", number 0x2c +Cyrillic_ze 0x2c +Cyrillic_ZE 0x2c shift + +# evdev 45 (0x2d), QKeyCode "x", number 0x2d +Cyrillic_dzhe 0x2d +Cyrillic_DZHE 0x2d shift + +# evdev 46 (0x2e), QKeyCode "c", number 0x2e +Cyrillic_tse 0x2e +Cyrillic_TSE 0x2e shift + +# evdev 47 (0x2f), QKeyCode "v", number 0x2f +Cyrillic_ve 0x2f +Cyrillic_VE 0x2f shift + +# evdev 48 (0x30), QKeyCode "b", number 0x30 +Cyrillic_be 0x30 +Cyrillic_BE 0x30 shift + +# evdev 49 (0x31), QKeyCode "n", number 0x31 +Cyrillic_en 0x31 +Cyrillic_EN 0x31 shift + +# evdev 50 (0x32), QKeyCode "m", number 0x32 +Cyrillic_em 0x32 +Cyrillic_EM 0x32 shift + +# evdev 51 (0x33), QKeyCode "comma", number 0x33 +comma 0x33 +semicolon 0x33 shift + +# evdev 52 (0x34), QKeyCode "dot", number 0x34 +period 0x34 +colon 0x34 shift + +# evdev 53 (0x35), QKeyCode "slash", number 0x35 +slash 0x35 +question 0x35 shift + +# evdev 54 (0x36), QKeyCode "shift_r", number 0x36 +Shift_R 0x36 + +# evdev 55 (0x37), QKeyCode "kp_multiply", number 0x37 +KP_Multiply 0x37 + +# evdev 56 (0x38), QKeyCode "alt", number 0x38 +Alt_L 0x38 +Meta_L 0x38 shift + +# evdev 57 (0x39), QKeyCode "spc", number 0x39 +space 0x39 + +# evdev 58 (0x3a), QKeyCode "caps_lock", number 0x3a +Caps_Lock 0x3a + +# evdev 59 (0x3b), QKeyCode "f1", number 0x3b +F1 0x3b + +# evdev 60 (0x3c), QKeyCode "f2", number 0x3c +F2 0x3c + +# evdev 61 (0x3d), QKeyCode "f3", number 0x3d +F3 0x3d + +# evdev 62 (0x3e), QKeyCode "f4", number 0x3e +F4 0x3e + +# evdev 63 (0x3f), QKeyCode "f5", number 0x3f +F5 0x3f + +# evdev 64 (0x40), QKeyCode "f6", number 0x40 +F6 0x40 + +# evdev 65 (0x41), QKeyCode "f7", number 0x41 +F7 0x41 + +# evdev 66 (0x42), QKeyCode "f8", number 0x42 +F8 0x42 + +# evdev 67 (0x43), QKeyCode "f9", number 0x43 +F9 0x43 + +# evdev 68 (0x44), QKeyCode "f10", number 0x44 +F10 0x44 + +# evdev 69 (0x45), QKeyCode "num_lock", number 0x45 +Num_Lock 0x45 + +# evdev 70 (0x46), QKeyCode "scroll_lock", number 0x46 +Scroll_Lock 0x46 + +# evdev 71 (0x47), QKeyCode "kp_7", number 0x47 +KP_Home 0x47 +KP_7 0x47 numlock + +# evdev 72 (0x48), QKeyCode "kp_8", number 0x48 +KP_Up 0x48 +KP_8 0x48 numlock + +# evdev 73 (0x49), QKeyCode "kp_9", number 0x49 +KP_Prior 0x49 +KP_9 0x49 numlock + +# evdev 74 (0x4a), QKeyCode "kp_subtract", number 0x4a +KP_Subtract 0x4a + +# evdev 75 (0x4b), QKeyCode "kp_4", number 0x4b +KP_Left 0x4b +KP_4 0x4b numlock + +# evdev 76 (0x4c), QKeyCode "kp_5", number 0x4c +KP_Begin 0x4c +KP_5 0x4c numlock + +# evdev 77 (0x4d), QKeyCode "kp_6", number 0x4d +KP_Right 0x4d +KP_6 0x4d numlock + +# evdev 78 (0x4e), QKeyCode "kp_add", number 0x4e +KP_Add 0x4e + +# evdev 79 (0x4f), QKeyCode "kp_1", number 0x4f +KP_End 0x4f +KP_1 0x4f numlock + +# evdev 80 (0x50), QKeyCode "kp_2", number 0x50 +KP_Down 0x50 +KP_2 0x50 numlock + +# evdev 81 (0x51), QKeyCode "kp_3", number 0x51 +KP_Next 0x51 +KP_3 0x51 numlock + +# evdev 82 (0x52), QKeyCode "kp_0", number 0x52 +KP_Insert 0x52 +KP_0 0x52 numlock + +# evdev 83 (0x53), QKeyCode "kp_decimal", number 0x53 +KP_Delete 0x53 +KP_Separator 0x53 numlock + +# evdev 84 (0x54): no evdev -> QKeyCode mapping (xkb keysym ISO_Level3_Shift) + +# evdev 85 (0x55): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 86 (0x56), QKeyCode "less", number 0x56 +less 0x56 +greater 0x56 shift +bar 0x56 altgr +brokenbar 0x56 shift altgr + +# evdev 87 (0x57), QKeyCode "f11", number 0x57 +F11 0x57 + +# evdev 88 (0x58), QKeyCode "f12", number 0x58 +F12 0x58 + +# evdev 89 (0x59), QKeyCode "ro", number 0x73 + +# evdev 90 (0x5a): no evdev -> QKeyCode mapping (xkb keysym Katakana) + +# evdev 91 (0x5b), QKeyCode "hiragana", number 0x77 +Hiragana 0x77 + +# evdev 92 (0x5c), QKeyCode "henkan", number 0x79 +Henkan_Mode 0x79 + +# evdev 93 (0x5d), QKeyCode "katakanahiragana", number 0x70 +Hiragana_Katakana 0x70 + +# evdev 94 (0x5e), QKeyCode "muhenkan", number 0x7b +Muhenkan 0x7b + +# evdev 95 (0x5f): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 96 (0x60), QKeyCode "kp_enter", number 0x9c +KP_Enter 0x9c + +# evdev 97 (0x61), QKeyCode "ctrl_r", number 0x9d +Control_R 0x9d + +# evdev 98 (0x62), QKeyCode "kp_divide", number 0xb5 +KP_Divide 0xb5 + +# evdev 99 (0x63), QKeyCode "sysrq", number 0x54 +Print 0x54 + +# evdev 100 (0x64), QKeyCode "alt_r", number 0xb8 +Alt_R 0xb8 +Meta_R 0xb8 shift + +# evdev 101 (0x65), QKeyCode "lf", number 0x5b +Linefeed 0x5b + +# evdev 102 (0x66), QKeyCode "home", number 0xc7 +Home 0xc7 + +# evdev 103 (0x67), QKeyCode "up", number 0xc8 +Up 0xc8 + +# evdev 104 (0x68), QKeyCode "pgup", number 0xc9 +Prior 0xc9 + +# evdev 105 (0x69), QKeyCode "left", number 0xcb +Left 0xcb + +# evdev 106 (0x6a), QKeyCode "right", number 0xcd +Right 0xcd + +# evdev 107 (0x6b), QKeyCode "end", number 0xcf +End 0xcf + +# evdev 108 (0x6c), QKeyCode "down", number 0xd0 +Down 0xd0 + +# evdev 109 (0x6d), QKeyCode "pgdn", number 0xd1 +Next 0xd1 + +# evdev 110 (0x6e), QKeyCode "insert", number 0xd2 +Insert 0xd2 + +# evdev 111 (0x6f), QKeyCode "delete", number 0xd3 +Delete 0xd3 + +# evdev 112 (0x70): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 113 (0x71), QKeyCode "audiomute", number 0xa0 +XF86AudioMute 0xa0 + +# evdev 114 (0x72), QKeyCode "volumedown", number 0xae +XF86AudioLowerVolume 0xae + +# evdev 115 (0x73), QKeyCode "volumeup", number 0xb0 +XF86AudioRaiseVolume 0xb0 + +# evdev 116 (0x74), QKeyCode "power", number 0xde +XF86PowerOff 0xde + +# evdev 117 (0x75), QKeyCode "kp_equals", number 0x59 +KP_Equal 0x59 + +# evdev 118 (0x76): no evdev -> QKeyCode mapping (xkb keysym plusminus) + +# evdev 119 (0x77), QKeyCode "pause", number 0xc6 +Pause 0xc6 + +# evdev 120 (0x78): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchA) + +# evdev 121 (0x79), QKeyCode "kp_comma", number 0x7e +KP_Decimal 0x7e + +# evdev 122 (0x7a): no evdev -> QKeyCode mapping (xkb keysym Hangul) + +# evdev 123 (0x7b): no evdev -> QKeyCode mapping (xkb keysym Hangul_Hanja) + +# evdev 124 (0x7c), QKeyCode "yen", number 0x7d + +# evdev 125 (0x7d), QKeyCode "meta_l", number 0xdb +Super_L 0xdb + +# evdev 126 (0x7e), QKeyCode "meta_r", number 0xdc +Super_R 0xdc + +# evdev 127 (0x7f), QKeyCode "compose", number 0xdd +Menu 0xdd + +# evdev 128 (0x80), QKeyCode "stop", number 0xe8 +Cancel 0xe8 + +# evdev 129 (0x81), QKeyCode "again", number 0x85 +Redo 0x85 + +# evdev 130 (0x82), QKeyCode "props", number 0x86 +SunProps 0x86 + +# evdev 131 (0x83), QKeyCode "undo", number 0x87 +Undo 0x87 + +# evdev 132 (0x84), QKeyCode "front", number 0x8c +SunFront 0x8c + +# evdev 133 (0x85), QKeyCode "copy", number 0xf8 +XF86Copy 0xf8 + +# evdev 134 (0x86), QKeyCode "open", number 0x64 +XF86Open 0x64 + +# evdev 135 (0x87), QKeyCode "paste", number 0x65 +XF86Paste 0x65 + +# evdev 136 (0x88), QKeyCode "find", number 0xc1 +Find 0xc1 + +# evdev 137 (0x89), QKeyCode "cut", number 0xbc +XF86Cut 0xbc + +# evdev 138 (0x8a), QKeyCode "help", number 0xf5 +Help 0xf5 + +# evdev 139 (0x8b), QKeyCode "menu", number 0x9e +XF86MenuKB 0x9e + +# evdev 140 (0x8c), QKeyCode "calculator", number 0xa1 +XF86Calculator 0xa1 + +# evdev 141 (0x8d): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 142 (0x8e), QKeyCode "sleep", number 0xdf +XF86Sleep 0xdf + +# evdev 143 (0x8f), QKeyCode "wake", number 0xe3 +XF86WakeUp 0xe3 + +# evdev 144 (0x90): no evdev -> QKeyCode mapping (xkb keysym XF86Explorer) + +# evdev 145 (0x91): no evdev -> QKeyCode mapping (xkb keysym XF86Send) + +# evdev 146 (0x92): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 147 (0x93): no evdev -> QKeyCode mapping (xkb keysym XF86Xfer) + +# evdev 148 (0x94): no evdev -> QKeyCode mapping (xkb keysym XF86Launch1) + +# evdev 149 (0x95): no evdev -> QKeyCode mapping (xkb keysym XF86Launch2) + +# evdev 150 (0x96): no evdev -> QKeyCode mapping (xkb keysym XF86WWW) + +# evdev 151 (0x97): no evdev -> QKeyCode mapping (xkb keysym XF86DOS) + +# evdev 152 (0x98): no evdev -> QKeyCode mapping (xkb keysym XF86ScreenSaver) + +# evdev 153 (0x99): no evdev -> QKeyCode mapping (xkb keysym XF86RotateWindows) + +# evdev 154 (0x9a): no evdev -> QKeyCode mapping (xkb keysym XF86TaskPane) + +# evdev 155 (0x9b), QKeyCode "mail", number 0xec +XF86Mail 0xec + +# evdev 156 (0x9c), QKeyCode "ac_bookmarks", number 0xe6 +XF86Favorites 0xe6 + +# evdev 157 (0x9d), QKeyCode "computer", number 0xeb +XF86MyComputer 0xeb + +# evdev 158 (0x9e), QKeyCode "ac_back", number 0xea +XF86Back 0xea + +# evdev 159 (0x9f), QKeyCode "ac_forward", number 0xe9 +XF86Forward 0xe9 + +# evdev 160 (0xa0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 161 (0xa1): no evdev -> QKeyCode mapping (xkb keysym XF86Eject) + +# evdev 162 (0xa2): no evdev -> QKeyCode mapping (xkb keysym XF86Eject) + +# evdev 163 (0xa3), QKeyCode "audionext", number 0x99 +XF86AudioNext 0x99 + +# evdev 164 (0xa4), QKeyCode "audioplay", number 0xa2 +XF86AudioPlay 0xa2 +XF86AudioPause 0xa2 shift + +# evdev 165 (0xa5), QKeyCode "audioprev", number 0x90 +XF86AudioPrev 0x90 + +# evdev 166 (0xa6), QKeyCode "audiostop", number 0xa4 +XF86AudioStop 0xa4 +XF86Eject 0xa4 shift + +# evdev 167 (0xa7): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRecord) + +# evdev 168 (0xa8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRewind) + +# evdev 169 (0xa9): no evdev -> QKeyCode mapping (xkb keysym XF86Phone) + +# evdev 170 (0xaa): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 171 (0xab): no evdev -> QKeyCode mapping (xkb keysym XF86Tools) + +# evdev 172 (0xac), QKeyCode "ac_home", number 0xb2 +XF86HomePage 0xb2 + +# evdev 173 (0xad), QKeyCode "ac_refresh", number 0xe7 +XF86Reload 0xe7 + +# evdev 174 (0xae): no evdev -> QKeyCode mapping (xkb keysym XF86Close) + +# evdev 175 (0xaf): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 176 (0xb0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 177 (0xb1): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollUp) + +# evdev 178 (0xb2): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollDown) + +# evdev 179 (0xb3): no evdev -> QKeyCode mapping (xkb keysym parenleft) + +# evdev 180 (0xb4): no evdev -> QKeyCode mapping (xkb keysym parenright) + +# evdev 181 (0xb5): no evdev -> QKeyCode mapping (xkb keysym XF86New) + +# evdev 182 (0xb6): no evdev -> QKeyCode mapping (xkb keysym Redo) + +# evdev 183 (0xb7): no evdev -> QKeyCode mapping (xkb keysym XF86Tools) + +# evdev 184 (0xb8): no evdev -> QKeyCode mapping (xkb keysym XF86Launch5) + +# evdev 185 (0xb9): no evdev -> QKeyCode mapping (xkb keysym XF86Launch6) + +# evdev 186 (0xba): no evdev -> QKeyCode mapping (xkb keysym XF86Launch7) + +# evdev 187 (0xbb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch8) + +# evdev 188 (0xbc): no evdev -> QKeyCode mapping (xkb keysym XF86Launch9) + +# evdev 189 (0xbd): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 190 (0xbe): no evdev -> QKeyCode mapping (xkb keysym XF86AudioMicMute) + +# evdev 191 (0xbf): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadToggle) + +# evdev 192 (0xc0): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOn) + +# evdev 193 (0xc1): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOff) + +# evdev 194 (0xc2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 195 (0xc3): no evdev -> QKeyCode mapping (xkb keysym Mode_switch) + +# evdev 196 (0xc4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 197 (0xc5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 198 (0xc6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 199 (0xc7): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 200 (0xc8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay) + +# evdev 201 (0xc9): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPause) + +# evdev 202 (0xca): no evdev -> QKeyCode mapping (xkb keysym XF86Launch3) + +# evdev 203 (0xcb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch4) + +# evdev 204 (0xcc): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchB) + +# evdev 205 (0xcd): no evdev -> QKeyCode mapping (xkb keysym XF86Suspend) + +# evdev 206 (0xce): no evdev -> QKeyCode mapping (xkb keysym XF86Close) + +# evdev 207 (0xcf): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay) + +# evdev 208 (0xd0): no evdev -> QKeyCode mapping (xkb keysym XF86AudioForward) + +# evdev 209 (0xd1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 210 (0xd2): no evdev -> QKeyCode mapping (xkb keysym Print) + +# evdev 211 (0xd3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 212 (0xd4): no evdev -> QKeyCode mapping (xkb keysym XF86WebCam) + +# evdev 213 (0xd5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 214 (0xd6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 215 (0xd7): no evdev -> QKeyCode mapping (xkb keysym XF86Mail) + +# evdev 216 (0xd8): no evdev -> QKeyCode mapping (xkb keysym XF86Messenger) + +# evdev 217 (0xd9): no evdev -> QKeyCode mapping (xkb keysym XF86Search) + +# evdev 218 (0xda): no evdev -> QKeyCode mapping (xkb keysym XF86Go) + +# evdev 219 (0xdb): no evdev -> QKeyCode mapping (xkb keysym XF86Finance) + +# evdev 220 (0xdc): no evdev -> QKeyCode mapping (xkb keysym XF86Game) + +# evdev 221 (0xdd): no evdev -> QKeyCode mapping (xkb keysym XF86Shop) + +# evdev 222 (0xde): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 223 (0xdf): no evdev -> QKeyCode mapping (xkb keysym Cancel) + +# evdev 224 (0xe0): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessDown) + +# evdev 225 (0xe1): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessUp) + +# evdev 226 (0xe2), QKeyCode "mediaselect", number 0xed +XF86AudioMedia 0xed + +# evdev 227 (0xe3): no evdev -> QKeyCode mapping (xkb keysym XF86Display) + +# evdev 228 (0xe4): no evdev -> QKeyCode mapping (xkb keysym XF86KbdLightOnOff) + +# evdev 229 (0xe5): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessDown) + +# evdev 230 (0xe6): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessUp) + +# evdev 231 (0xe7): no evdev -> QKeyCode mapping (xkb keysym XF86Send) + +# evdev 232 (0xe8): no evdev -> QKeyCode mapping (xkb keysym XF86Reply) + +# evdev 233 (0xe9): no evdev -> QKeyCode mapping (xkb keysym XF86MailForward) + +# evdev 234 (0xea): no evdev -> QKeyCode mapping (xkb keysym XF86Save) + +# evdev 235 (0xeb): no evdev -> QKeyCode mapping (xkb keysym XF86Documents) + +# evdev 236 (0xec): no evdev -> QKeyCode mapping (xkb keysym XF86Battery) + +# evdev 237 (0xed): no evdev -> QKeyCode mapping (xkb keysym XF86Bluetooth) + +# evdev 238 (0xee): no evdev -> QKeyCode mapping (xkb keysym XF86WLAN) + +# evdev 239 (0xef): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 240 (0xf0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 241 (0xf1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 242 (0xf2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 243 (0xf3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 244 (0xf4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 245 (0xf5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 246 (0xf6): no evdev -> QKeyCode mapping (xkb keysym Invalid) + +# evdev 247 (0xf7): no evdev -> QKeyCode mapping (xkb keysym Invalid) + +# +# quirks section start +# +# Sometimes multiple keysyms map to the same keycodes. +# The keycode -> keysym lookup finds only one of the +# keysyms. So append them here. +# + +Print 0x54 +Sys_Req 0x54 +Execute 0x54 +KP_Decimal 0x53 numlock +KP_Separator 0x53 numlock +Alt_R 0xb8 +ISO_Level3_Shift 0xb8 +Mode_switch 0xb8 + +# quirks section end diff --git a/app/src/main/assets/roms/keymaps/nl b/app/src/main/assets/roms/keymaps/nl new file mode 100644 index 0000000..1579829 --- /dev/null +++ b/app/src/main/assets/roms/keymaps/nl @@ -0,0 +1,843 @@ +# +# generated by qemu-keymap +# model : pc105 +# layout : nl +# variant : - +# options : - + +# name: "Dutch" + +# modifiers +# 0: Shift +# 1: Lock +# 2: Control +# 3: Mod1 +# 4: Mod2 +# 5: Mod3 +# 6: Mod4 +# 7: Mod5 +# 8: NumLock +# 9: Alt +# 10: LevelThree +# 11: LAlt +# 12: RAlt +# 13: RControl +# 14: LControl +# 15: ScrollLock +# 16: LevelFive +# 17: AltGr +# 18: Meta +# 19: Super +# 20: Hyper + +# evdev 1 (0x1), QKeyCode "esc", number 0x1 +Escape 0x01 + +# evdev 2 (0x2), QKeyCode "1", number 0x2 +1 0x02 +exclam 0x02 shift +onesuperior 0x02 altgr +exclamdown 0x02 shift altgr + +# evdev 3 (0x3), QKeyCode "2", number 0x3 +2 0x03 +quotedbl 0x03 shift +twosuperior 0x03 altgr +oneeighth 0x03 shift altgr + +# evdev 4 (0x4), QKeyCode "3", number 0x4 +3 0x04 +numbersign 0x04 shift +threesuperior 0x04 altgr +sterling 0x04 shift altgr + +# evdev 5 (0x5), QKeyCode "4", number 0x5 +4 0x05 +dollar 0x05 shift +onequarter 0x05 altgr + +# evdev 6 (0x6), QKeyCode "5", number 0x6 +5 0x06 +percent 0x06 shift +onehalf 0x06 altgr +threeeighths 0x06 shift altgr + +# evdev 7 (0x7), QKeyCode "6", number 0x7 +6 0x07 +ampersand 0x07 shift +threequarters 0x07 altgr +fiveeighths 0x07 shift altgr + +# evdev 8 (0x8), QKeyCode "7", number 0x8 +7 0x08 +underscore 0x08 shift +sterling 0x08 altgr +seveneighths 0x08 shift altgr + +# evdev 9 (0x9), QKeyCode "8", number 0x9 +8 0x09 +parenleft 0x09 shift +braceleft 0x09 altgr +bracketleft 0x09 shift altgr + +# evdev 10 (0xa), QKeyCode "9", number 0xa +9 0x0a +parenright 0x0a shift +braceright 0x0a altgr +bracketright 0x0a shift altgr + +# evdev 11 (0xb), QKeyCode "0", number 0xb +0 0x0b +apostrophe 0x0b shift +degree 0x0b altgr +trademark 0x0b shift altgr + +# evdev 12 (0xc), QKeyCode "minus", number 0xc +slash 0x0c +question 0x0c shift +backslash 0x0c altgr +questiondown 0x0c shift altgr + +# evdev 13 (0xd), QKeyCode "equal", number 0xd +degree 0x0d +dead_tilde 0x0d shift +dead_cedilla 0x0d altgr +dead_ogonek 0x0d shift altgr + +# evdev 14 (0xe), QKeyCode "backspace", number 0xe +BackSpace 0x0e + +# evdev 15 (0xf), QKeyCode "tab", number 0xf +Tab 0x0f +ISO_Left_Tab 0x0f shift + +# evdev 16 (0x10), QKeyCode "q", number 0x10 +q 0x10 +Q 0x10 shift +at 0x10 altgr +Greek_OMEGA 0x10 shift altgr + +# evdev 17 (0x11), QKeyCode "w", number 0x11 +w 0x11 +W 0x11 shift +lstroke 0x11 altgr +Lstroke 0x11 shift altgr + +# evdev 18 (0x12), QKeyCode "e", number 0x12 +e 0x12 +E 0x12 shift +EuroSign 0x12 altgr +cent 0x12 shift altgr + +# evdev 19 (0x13), QKeyCode "r", number 0x13 +r 0x13 +R 0x13 shift +paragraph 0x13 altgr +registered 0x13 shift altgr + +# evdev 20 (0x14), QKeyCode "t", number 0x14 +t 0x14 +T 0x14 shift +thorn 0x14 altgr +THORN 0x14 shift altgr + +# evdev 21 (0x15), QKeyCode "y", number 0x15 +y 0x15 +Y 0x15 shift +ydiaeresis 0x15 altgr +yen 0x15 shift altgr + +# evdev 22 (0x16), QKeyCode "u", number 0x16 +u 0x16 +U 0x16 shift +udiaeresis 0x16 altgr +Udiaeresis 0x16 shift altgr + +# evdev 23 (0x17), QKeyCode "i", number 0x17 +i 0x17 +I 0x17 shift +idiaeresis 0x17 altgr +Idiaeresis 0x17 shift altgr + +# evdev 24 (0x18), QKeyCode "o", number 0x18 +o 0x18 +O 0x18 shift +ograve 0x18 altgr +Ograve 0x18 shift altgr + +# evdev 25 (0x19), QKeyCode "p", number 0x19 +p 0x19 +P 0x19 shift +paragraph 0x19 altgr +THORN 0x19 shift altgr + +# evdev 26 (0x1a), QKeyCode "bracket_left", number 0x1a +dead_diaeresis 0x1a +dead_circumflex 0x1a shift +asciitilde 0x1a altgr +asciicircum 0x1a shift altgr + +# evdev 27 (0x1b), QKeyCode "bracket_right", number 0x1b +asterisk 0x1b +bar 0x1b shift +dead_tilde 0x1b altgr +dead_macron 0x1b shift altgr + +# evdev 28 (0x1c), QKeyCode "ret", number 0x1c +Return 0x1c + +# evdev 29 (0x1d), QKeyCode "ctrl", number 0x1d +Control_L 0x1d + +# evdev 30 (0x1e), QKeyCode "a", number 0x1e +a 0x1e +A 0x1e shift +aacute 0x1e altgr +Aacute 0x1e shift altgr + +# evdev 31 (0x1f), QKeyCode "s", number 0x1f +s 0x1f +S 0x1f shift +ssharp 0x1f altgr +section 0x1f shift altgr + +# evdev 32 (0x20), QKeyCode "d", number 0x20 +d 0x20 +D 0x20 shift +eth 0x20 altgr +ETH 0x20 shift altgr + +# evdev 33 (0x21), QKeyCode "f", number 0x21 +f 0x21 +F 0x21 shift +ordfeminine 0x21 altgr + +# evdev 34 (0x22), QKeyCode "g", number 0x22 +g 0x22 +G 0x22 shift +eng 0x22 altgr +ENG 0x22 shift altgr + +# evdev 35 (0x23), QKeyCode "h", number 0x23 +h 0x23 +H 0x23 shift +hstroke 0x23 altgr +Hstroke 0x23 shift altgr + +# evdev 36 (0x24), QKeyCode "j", number 0x24 +j 0x24 +J 0x24 shift +dead_hook 0x24 altgr +dead_horn 0x24 shift altgr + +# evdev 37 (0x25), QKeyCode "k", number 0x25 +k 0x25 +K 0x25 shift +kra 0x25 altgr +ampersand 0x25 shift altgr + +# evdev 38 (0x26), QKeyCode "l", number 0x26 +l 0x26 +L 0x26 shift +lstroke 0x26 altgr +Lstroke 0x26 shift altgr + +# evdev 39 (0x27), QKeyCode "semicolon", number 0x27 +plus 0x27 +plusminus 0x27 shift +dead_acute 0x27 altgr +dead_doubleacute 0x27 shift altgr + +# evdev 40 (0x28), QKeyCode "apostrophe", number 0x28 +dead_acute 0x28 +dead_grave 0x28 shift +apostrophe 0x28 altgr +grave 0x28 shift altgr + +# evdev 41 (0x29), QKeyCode "grave_accent", number 0x29 +at 0x29 +section 0x29 shift +notsign 0x29 altgr + +# evdev 42 (0x2a), QKeyCode "shift", number 0x2a +Shift_L 0x2a + +# evdev 43 (0x2b), QKeyCode "backslash", number 0x2b +less 0x2b +greater 0x2b shift +dead_grave 0x2b altgr +dead_breve 0x2b shift altgr + +# evdev 44 (0x2c), QKeyCode "z", number 0x2c +z 0x2c +Z 0x2c shift +guillemotleft 0x2c altgr +less 0x2c shift altgr + +# evdev 45 (0x2d), QKeyCode "x", number 0x2d +x 0x2d +X 0x2d shift +guillemotright 0x2d altgr +greater 0x2d shift altgr + +# evdev 46 (0x2e), QKeyCode "c", number 0x2e +c 0x2e +C 0x2e shift +cent 0x2e altgr +copyright 0x2e shift altgr + +# evdev 47 (0x2f), QKeyCode "v", number 0x2f +v 0x2f +V 0x2f shift +leftdoublequotemark 0x2f altgr +leftsinglequotemark 0x2f shift altgr + +# evdev 48 (0x30), QKeyCode "b", number 0x30 +b 0x30 +B 0x30 shift +rightdoublequotemark 0x30 altgr +rightsinglequotemark 0x30 shift altgr + +# evdev 49 (0x31), QKeyCode "n", number 0x31 +n 0x31 +N 0x31 shift +ntilde 0x31 altgr +Ntilde 0x31 shift altgr + +# evdev 50 (0x32), QKeyCode "m", number 0x32 +m 0x32 +M 0x32 shift +Greek_mu 0x32 altgr +masculine 0x32 shift altgr + +# evdev 51 (0x33), QKeyCode "comma", number 0x33 +comma 0x33 +semicolon 0x33 shift +cedilla 0x33 altgr +guillemotleft 0x33 shift altgr + +# evdev 52 (0x34), QKeyCode "dot", number 0x34 +period 0x34 +colon 0x34 shift +periodcentered 0x34 altgr +guillemotright 0x34 shift altgr + +# evdev 53 (0x35), QKeyCode "slash", number 0x35 +minus 0x35 +equal 0x35 shift +hyphen 0x35 altgr +dead_abovedot 0x35 shift altgr + +# evdev 54 (0x36), QKeyCode "shift_r", number 0x36 +Shift_R 0x36 + +# evdev 55 (0x37), QKeyCode "kp_multiply", number 0x37 +KP_Multiply 0x37 + +# evdev 56 (0x38), QKeyCode "alt", number 0x38 +Alt_L 0x38 +Meta_L 0x38 shift + +# evdev 57 (0x39), QKeyCode "spc", number 0x39 +space 0x39 + +# evdev 58 (0x3a), QKeyCode "caps_lock", number 0x3a +Caps_Lock 0x3a + +# evdev 59 (0x3b), QKeyCode "f1", number 0x3b +F1 0x3b + +# evdev 60 (0x3c), QKeyCode "f2", number 0x3c +F2 0x3c + +# evdev 61 (0x3d), QKeyCode "f3", number 0x3d +F3 0x3d + +# evdev 62 (0x3e), QKeyCode "f4", number 0x3e +F4 0x3e + +# evdev 63 (0x3f), QKeyCode "f5", number 0x3f +F5 0x3f + +# evdev 64 (0x40), QKeyCode "f6", number 0x40 +F6 0x40 + +# evdev 65 (0x41), QKeyCode "f7", number 0x41 +F7 0x41 + +# evdev 66 (0x42), QKeyCode "f8", number 0x42 +F8 0x42 + +# evdev 67 (0x43), QKeyCode "f9", number 0x43 +F9 0x43 + +# evdev 68 (0x44), QKeyCode "f10", number 0x44 +F10 0x44 + +# evdev 69 (0x45), QKeyCode "num_lock", number 0x45 +Num_Lock 0x45 + +# evdev 70 (0x46), QKeyCode "scroll_lock", number 0x46 +Scroll_Lock 0x46 + +# evdev 71 (0x47), QKeyCode "kp_7", number 0x47 +KP_Home 0x47 +KP_7 0x47 numlock + +# evdev 72 (0x48), QKeyCode "kp_8", number 0x48 +KP_Up 0x48 +KP_8 0x48 numlock + +# evdev 73 (0x49), QKeyCode "kp_9", number 0x49 +KP_Prior 0x49 +KP_9 0x49 numlock + +# evdev 74 (0x4a), QKeyCode "kp_subtract", number 0x4a +KP_Subtract 0x4a + +# evdev 75 (0x4b), QKeyCode "kp_4", number 0x4b +KP_Left 0x4b +KP_4 0x4b numlock + +# evdev 76 (0x4c), QKeyCode "kp_5", number 0x4c +KP_Begin 0x4c +KP_5 0x4c numlock + +# evdev 77 (0x4d), QKeyCode "kp_6", number 0x4d +KP_Right 0x4d +KP_6 0x4d numlock + +# evdev 78 (0x4e), QKeyCode "kp_add", number 0x4e +KP_Add 0x4e + +# evdev 79 (0x4f), QKeyCode "kp_1", number 0x4f +KP_End 0x4f +KP_1 0x4f numlock + +# evdev 80 (0x50), QKeyCode "kp_2", number 0x50 +KP_Down 0x50 +KP_2 0x50 numlock + +# evdev 81 (0x51), QKeyCode "kp_3", number 0x51 +KP_Next 0x51 +KP_3 0x51 numlock + +# evdev 82 (0x52), QKeyCode "kp_0", number 0x52 +KP_Insert 0x52 +KP_0 0x52 numlock + +# evdev 83 (0x53), QKeyCode "kp_decimal", number 0x53 +KP_Delete 0x53 +KP_Decimal 0x53 numlock + +# evdev 84 (0x54): no evdev -> QKeyCode mapping (xkb keysym ISO_Level3_Shift) + +# evdev 85 (0x55): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 86 (0x56), QKeyCode "less", number 0x56 +bracketright 0x56 +bracketleft 0x56 shift +bar 0x56 altgr +brokenbar 0x56 shift altgr + +# evdev 87 (0x57), QKeyCode "f11", number 0x57 +F11 0x57 + +# evdev 88 (0x58), QKeyCode "f12", number 0x58 +F12 0x58 + +# evdev 89 (0x59), QKeyCode "ro", number 0x73 + +# evdev 90 (0x5a): no evdev -> QKeyCode mapping (xkb keysym Katakana) + +# evdev 91 (0x5b), QKeyCode "hiragana", number 0x77 +Hiragana 0x77 + +# evdev 92 (0x5c), QKeyCode "henkan", number 0x79 +Henkan_Mode 0x79 + +# evdev 93 (0x5d), QKeyCode "katakanahiragana", number 0x70 +Hiragana_Katakana 0x70 + +# evdev 94 (0x5e), QKeyCode "muhenkan", number 0x7b +Muhenkan 0x7b + +# evdev 95 (0x5f): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 96 (0x60), QKeyCode "kp_enter", number 0x9c +KP_Enter 0x9c + +# evdev 97 (0x61), QKeyCode "ctrl_r", number 0x9d +Control_R 0x9d + +# evdev 98 (0x62), QKeyCode "kp_divide", number 0xb5 +KP_Divide 0xb5 + +# evdev 99 (0x63), QKeyCode "sysrq", number 0x54 +Print 0x54 + +# evdev 100 (0x64), QKeyCode "alt_r", number 0xb8 +ISO_Level3_Shift 0xb8 + +# evdev 101 (0x65), QKeyCode "lf", number 0x5b +Linefeed 0x5b + +# evdev 102 (0x66), QKeyCode "home", number 0xc7 +Home 0xc7 + +# evdev 103 (0x67), QKeyCode "up", number 0xc8 +Up 0xc8 + +# evdev 104 (0x68), QKeyCode "pgup", number 0xc9 +Prior 0xc9 + +# evdev 105 (0x69), QKeyCode "left", number 0xcb +Left 0xcb + +# evdev 106 (0x6a), QKeyCode "right", number 0xcd +Right 0xcd + +# evdev 107 (0x6b), QKeyCode "end", number 0xcf +End 0xcf + +# evdev 108 (0x6c), QKeyCode "down", number 0xd0 +Down 0xd0 + +# evdev 109 (0x6d), QKeyCode "pgdn", number 0xd1 +Next 0xd1 + +# evdev 110 (0x6e), QKeyCode "insert", number 0xd2 +Insert 0xd2 + +# evdev 111 (0x6f), QKeyCode "delete", number 0xd3 +Delete 0xd3 + +# evdev 112 (0x70): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 113 (0x71), QKeyCode "audiomute", number 0xa0 +XF86AudioMute 0xa0 + +# evdev 114 (0x72), QKeyCode "volumedown", number 0xae +XF86AudioLowerVolume 0xae + +# evdev 115 (0x73), QKeyCode "volumeup", number 0xb0 +XF86AudioRaiseVolume 0xb0 + +# evdev 116 (0x74), QKeyCode "power", number 0xde +XF86PowerOff 0xde + +# evdev 117 (0x75), QKeyCode "kp_equals", number 0x59 +KP_Equal 0x59 + +# evdev 118 (0x76): no evdev -> QKeyCode mapping (xkb keysym plusminus) + +# evdev 119 (0x77), QKeyCode "pause", number 0xc6 +Pause 0xc6 + +# evdev 120 (0x78): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchA) + +# evdev 121 (0x79), QKeyCode "kp_comma", number 0x7e +KP_Decimal 0x7e + +# evdev 122 (0x7a): no evdev -> QKeyCode mapping (xkb keysym Hangul) + +# evdev 123 (0x7b): no evdev -> QKeyCode mapping (xkb keysym Hangul_Hanja) + +# evdev 124 (0x7c), QKeyCode "yen", number 0x7d + +# evdev 125 (0x7d), QKeyCode "meta_l", number 0xdb +Super_L 0xdb + +# evdev 126 (0x7e), QKeyCode "meta_r", number 0xdc +Super_R 0xdc + +# evdev 127 (0x7f), QKeyCode "compose", number 0xdd +Menu 0xdd + +# evdev 128 (0x80), QKeyCode "stop", number 0xe8 +Cancel 0xe8 + +# evdev 129 (0x81), QKeyCode "again", number 0x85 +Redo 0x85 + +# evdev 130 (0x82), QKeyCode "props", number 0x86 +SunProps 0x86 + +# evdev 131 (0x83), QKeyCode "undo", number 0x87 +Undo 0x87 + +# evdev 132 (0x84), QKeyCode "front", number 0x8c +SunFront 0x8c + +# evdev 133 (0x85), QKeyCode "copy", number 0xf8 +XF86Copy 0xf8 + +# evdev 134 (0x86), QKeyCode "open", number 0x64 +XF86Open 0x64 + +# evdev 135 (0x87), QKeyCode "paste", number 0x65 +XF86Paste 0x65 + +# evdev 136 (0x88), QKeyCode "find", number 0xc1 +Find 0xc1 + +# evdev 137 (0x89), QKeyCode "cut", number 0xbc +XF86Cut 0xbc + +# evdev 138 (0x8a), QKeyCode "help", number 0xf5 +Help 0xf5 + +# evdev 139 (0x8b), QKeyCode "menu", number 0x9e +XF86MenuKB 0x9e + +# evdev 140 (0x8c), QKeyCode "calculator", number 0xa1 +XF86Calculator 0xa1 + +# evdev 141 (0x8d): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 142 (0x8e), QKeyCode "sleep", number 0xdf +XF86Sleep 0xdf + +# evdev 143 (0x8f), QKeyCode "wake", number 0xe3 +XF86WakeUp 0xe3 + +# evdev 144 (0x90): no evdev -> QKeyCode mapping (xkb keysym XF86Explorer) + +# evdev 145 (0x91): no evdev -> QKeyCode mapping (xkb keysym XF86Send) + +# evdev 146 (0x92): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 147 (0x93): no evdev -> QKeyCode mapping (xkb keysym XF86Xfer) + +# evdev 148 (0x94): no evdev -> QKeyCode mapping (xkb keysym XF86Launch1) + +# evdev 149 (0x95): no evdev -> QKeyCode mapping (xkb keysym XF86Launch2) + +# evdev 150 (0x96): no evdev -> QKeyCode mapping (xkb keysym XF86WWW) + +# evdev 151 (0x97): no evdev -> QKeyCode mapping (xkb keysym XF86DOS) + +# evdev 152 (0x98): no evdev -> QKeyCode mapping (xkb keysym XF86ScreenSaver) + +# evdev 153 (0x99): no evdev -> QKeyCode mapping (xkb keysym XF86RotateWindows) + +# evdev 154 (0x9a): no evdev -> QKeyCode mapping (xkb keysym XF86TaskPane) + +# evdev 155 (0x9b), QKeyCode "mail", number 0xec +XF86Mail 0xec + +# evdev 156 (0x9c), QKeyCode "ac_bookmarks", number 0xe6 +XF86Favorites 0xe6 + +# evdev 157 (0x9d), QKeyCode "computer", number 0xeb +XF86MyComputer 0xeb + +# evdev 158 (0x9e), QKeyCode "ac_back", number 0xea +XF86Back 0xea + +# evdev 159 (0x9f), QKeyCode "ac_forward", number 0xe9 +XF86Forward 0xe9 + +# evdev 160 (0xa0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 161 (0xa1): no evdev -> QKeyCode mapping (xkb keysym XF86Eject) + +# evdev 162 (0xa2): no evdev -> QKeyCode mapping (xkb keysym XF86Eject) + +# evdev 163 (0xa3), QKeyCode "audionext", number 0x99 +XF86AudioNext 0x99 + +# evdev 164 (0xa4), QKeyCode "audioplay", number 0xa2 +XF86AudioPlay 0xa2 +XF86AudioPause 0xa2 shift + +# evdev 165 (0xa5), QKeyCode "audioprev", number 0x90 +XF86AudioPrev 0x90 + +# evdev 166 (0xa6), QKeyCode "audiostop", number 0xa4 +XF86AudioStop 0xa4 +XF86Eject 0xa4 shift + +# evdev 167 (0xa7): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRecord) + +# evdev 168 (0xa8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRewind) + +# evdev 169 (0xa9): no evdev -> QKeyCode mapping (xkb keysym XF86Phone) + +# evdev 170 (0xaa): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 171 (0xab): no evdev -> QKeyCode mapping (xkb keysym XF86Tools) + +# evdev 172 (0xac), QKeyCode "ac_home", number 0xb2 +XF86HomePage 0xb2 + +# evdev 173 (0xad), QKeyCode "ac_refresh", number 0xe7 +XF86Reload 0xe7 + +# evdev 174 (0xae): no evdev -> QKeyCode mapping (xkb keysym XF86Close) + +# evdev 175 (0xaf): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 176 (0xb0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 177 (0xb1): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollUp) + +# evdev 178 (0xb2): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollDown) + +# evdev 179 (0xb3): no evdev -> QKeyCode mapping (xkb keysym parenleft) + +# evdev 180 (0xb4): no evdev -> QKeyCode mapping (xkb keysym parenright) + +# evdev 181 (0xb5): no evdev -> QKeyCode mapping (xkb keysym XF86New) + +# evdev 182 (0xb6): no evdev -> QKeyCode mapping (xkb keysym Redo) + +# evdev 183 (0xb7): no evdev -> QKeyCode mapping (xkb keysym XF86Tools) + +# evdev 184 (0xb8): no evdev -> QKeyCode mapping (xkb keysym XF86Launch5) + +# evdev 185 (0xb9): no evdev -> QKeyCode mapping (xkb keysym XF86Launch6) + +# evdev 186 (0xba): no evdev -> QKeyCode mapping (xkb keysym XF86Launch7) + +# evdev 187 (0xbb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch8) + +# evdev 188 (0xbc): no evdev -> QKeyCode mapping (xkb keysym XF86Launch9) + +# evdev 189 (0xbd): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 190 (0xbe): no evdev -> QKeyCode mapping (xkb keysym XF86AudioMicMute) + +# evdev 191 (0xbf): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadToggle) + +# evdev 192 (0xc0): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOn) + +# evdev 193 (0xc1): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOff) + +# evdev 194 (0xc2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 195 (0xc3): no evdev -> QKeyCode mapping (xkb keysym Mode_switch) + +# evdev 196 (0xc4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 197 (0xc5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 198 (0xc6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 199 (0xc7): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 200 (0xc8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay) + +# evdev 201 (0xc9): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPause) + +# evdev 202 (0xca): no evdev -> QKeyCode mapping (xkb keysym XF86Launch3) + +# evdev 203 (0xcb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch4) + +# evdev 204 (0xcc): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchB) + +# evdev 205 (0xcd): no evdev -> QKeyCode mapping (xkb keysym XF86Suspend) + +# evdev 206 (0xce): no evdev -> QKeyCode mapping (xkb keysym XF86Close) + +# evdev 207 (0xcf): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay) + +# evdev 208 (0xd0): no evdev -> QKeyCode mapping (xkb keysym XF86AudioForward) + +# evdev 209 (0xd1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 210 (0xd2): no evdev -> QKeyCode mapping (xkb keysym Print) + +# evdev 211 (0xd3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 212 (0xd4): no evdev -> QKeyCode mapping (xkb keysym XF86WebCam) + +# evdev 213 (0xd5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 214 (0xd6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 215 (0xd7): no evdev -> QKeyCode mapping (xkb keysym XF86Mail) + +# evdev 216 (0xd8): no evdev -> QKeyCode mapping (xkb keysym XF86Messenger) + +# evdev 217 (0xd9): no evdev -> QKeyCode mapping (xkb keysym XF86Search) + +# evdev 218 (0xda): no evdev -> QKeyCode mapping (xkb keysym XF86Go) + +# evdev 219 (0xdb): no evdev -> QKeyCode mapping (xkb keysym XF86Finance) + +# evdev 220 (0xdc): no evdev -> QKeyCode mapping (xkb keysym XF86Game) + +# evdev 221 (0xdd): no evdev -> QKeyCode mapping (xkb keysym XF86Shop) + +# evdev 222 (0xde): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 223 (0xdf): no evdev -> QKeyCode mapping (xkb keysym Cancel) + +# evdev 224 (0xe0): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessDown) + +# evdev 225 (0xe1): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessUp) + +# evdev 226 (0xe2), QKeyCode "mediaselect", number 0xed +XF86AudioMedia 0xed + +# evdev 227 (0xe3): no evdev -> QKeyCode mapping (xkb keysym XF86Display) + +# evdev 228 (0xe4): no evdev -> QKeyCode mapping (xkb keysym XF86KbdLightOnOff) + +# evdev 229 (0xe5): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessDown) + +# evdev 230 (0xe6): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessUp) + +# evdev 231 (0xe7): no evdev -> QKeyCode mapping (xkb keysym XF86Send) + +# evdev 232 (0xe8): no evdev -> QKeyCode mapping (xkb keysym XF86Reply) + +# evdev 233 (0xe9): no evdev -> QKeyCode mapping (xkb keysym XF86MailForward) + +# evdev 234 (0xea): no evdev -> QKeyCode mapping (xkb keysym XF86Save) + +# evdev 235 (0xeb): no evdev -> QKeyCode mapping (xkb keysym XF86Documents) + +# evdev 236 (0xec): no evdev -> QKeyCode mapping (xkb keysym XF86Battery) + +# evdev 237 (0xed): no evdev -> QKeyCode mapping (xkb keysym XF86Bluetooth) + +# evdev 238 (0xee): no evdev -> QKeyCode mapping (xkb keysym XF86WLAN) + +# evdev 239 (0xef): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 240 (0xf0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 241 (0xf1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 242 (0xf2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 243 (0xf3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 244 (0xf4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 245 (0xf5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 246 (0xf6): no evdev -> QKeyCode mapping (xkb keysym Invalid) + +# evdev 247 (0xf7): no evdev -> QKeyCode mapping (xkb keysym Invalid) + +# +# quirks section start +# +# Sometimes multiple keysyms map to the same keycodes. +# The keycode -> keysym lookup finds only one of the +# keysyms. So append them here. +# + +Print 0x54 +Sys_Req 0x54 +Execute 0x54 +KP_Decimal 0x53 numlock +KP_Separator 0x53 numlock +Alt_R 0xb8 +ISO_Level3_Shift 0xb8 +Mode_switch 0xb8 + +# quirks section end diff --git a/app/src/main/assets/roms/keymaps/no b/app/src/main/assets/roms/keymaps/no new file mode 100644 index 0000000..cd634e7 --- /dev/null +++ b/app/src/main/assets/roms/keymaps/no @@ -0,0 +1,857 @@ +# +# generated by qemu-keymap +# model : pc105 +# layout : no +# variant : - +# options : - + +# name: "Norwegian" + +# modifiers +# 0: Shift +# 1: Lock +# 2: Control +# 3: Mod1 +# 4: Mod2 +# 5: Mod3 +# 6: Mod4 +# 7: Mod5 +# 8: NumLock +# 9: Alt +# 10: LevelThree +# 11: LAlt +# 12: RAlt +# 13: RControl +# 14: LControl +# 15: ScrollLock +# 16: LevelFive +# 17: AltGr +# 18: Meta +# 19: Super +# 20: Hyper + +# evdev 1 (0x1), QKeyCode "esc", number 0x1 +Escape 0x01 + +# evdev 2 (0x2), QKeyCode "1", number 0x2 +1 0x02 +exclam 0x02 shift +exclamdown 0x02 altgr +onesuperior 0x02 shift altgr + +# evdev 3 (0x3), QKeyCode "2", number 0x3 +2 0x03 +quotedbl 0x03 shift +at 0x03 altgr +twosuperior 0x03 shift altgr + +# evdev 4 (0x4), QKeyCode "3", number 0x4 +3 0x04 +numbersign 0x04 shift +sterling 0x04 altgr +threesuperior 0x04 shift altgr + +# evdev 5 (0x5), QKeyCode "4", number 0x5 +4 0x05 +currency 0x05 shift +dollar 0x05 altgr +onequarter 0x05 shift altgr + +# evdev 6 (0x6), QKeyCode "5", number 0x6 +5 0x06 +percent 0x06 shift +onehalf 0x06 altgr +U2030 0x06 shift altgr + +# evdev 7 (0x7), QKeyCode "6", number 0x7 +6 0x07 +ampersand 0x07 shift +yen 0x07 altgr +fiveeighths 0x07 shift altgr + +# evdev 8 (0x8), QKeyCode "7", number 0x8 +7 0x08 +slash 0x08 shift +braceleft 0x08 altgr +division 0x08 shift altgr + +# evdev 9 (0x9), QKeyCode "8", number 0x9 +8 0x09 +parenleft 0x09 shift +bracketleft 0x09 altgr +guillemotleft 0x09 shift altgr + +# evdev 10 (0xa), QKeyCode "9", number 0xa +9 0x0a +parenright 0x0a shift +bracketright 0x0a altgr +guillemotright 0x0a shift altgr + +# evdev 11 (0xb), QKeyCode "0", number 0xb +0 0x0b +equal 0x0b shift +braceright 0x0b altgr +degree 0x0b shift altgr + +# evdev 12 (0xc), QKeyCode "minus", number 0xc +plus 0x0c +question 0x0c shift +plusminus 0x0c altgr +questiondown 0x0c shift altgr + +# evdev 13 (0xd), QKeyCode "equal", number 0xd +backslash 0x0d +dead_grave 0x0d shift +dead_acute 0x0d altgr +notsign 0x0d shift altgr + +# evdev 14 (0xe), QKeyCode "backspace", number 0xe +BackSpace 0x0e + +# evdev 15 (0xf), QKeyCode "tab", number 0xf +Tab 0x0f +ISO_Left_Tab 0x0f shift + +# evdev 16 (0x10), QKeyCode "q", number 0x10 +q 0x10 +Q 0x10 shift +at 0x10 altgr +Greek_OMEGA 0x10 shift altgr + +# evdev 17 (0x11), QKeyCode "w", number 0x11 +w 0x11 +W 0x11 shift +lstroke 0x11 altgr +Lstroke 0x11 shift altgr + +# evdev 18 (0x12), QKeyCode "e", number 0x12 +e 0x12 +E 0x12 shift +EuroSign 0x12 altgr +cent 0x12 shift altgr + +# evdev 19 (0x13), QKeyCode "r", number 0x13 +r 0x13 +R 0x13 shift +registered 0x13 altgr +trademark 0x13 shift altgr + +# evdev 20 (0x14), QKeyCode "t", number 0x14 +t 0x14 +T 0x14 shift +thorn 0x14 altgr +THORN 0x14 shift altgr + +# evdev 21 (0x15), QKeyCode "y", number 0x15 +y 0x15 +Y 0x15 shift +leftarrow 0x15 altgr +yen 0x15 shift altgr + +# evdev 22 (0x16), QKeyCode "u", number 0x16 +u 0x16 +U 0x16 shift +downarrow 0x16 altgr +uparrow 0x16 shift altgr + +# evdev 23 (0x17), QKeyCode "i", number 0x17 +i 0x17 +I 0x17 shift +rightarrow 0x17 altgr +idotless 0x17 shift altgr + +# evdev 24 (0x18), QKeyCode "o", number 0x18 +o 0x18 +O 0x18 shift +oe 0x18 altgr +OE 0x18 shift altgr + +# evdev 25 (0x19), QKeyCode "p", number 0x19 +p 0x19 +P 0x19 shift +Greek_pi 0x19 altgr +Greek_PI 0x19 shift altgr + +# evdev 26 (0x1a), QKeyCode "bracket_left", number 0x1a +aring 0x1a +Aring 0x1a shift +dead_diaeresis 0x1a altgr +dead_abovering 0x1a shift altgr + +# evdev 27 (0x1b), QKeyCode "bracket_right", number 0x1b +dead_diaeresis 0x1b +dead_circumflex 0x1b shift +dead_tilde 0x1b altgr +dead_caron 0x1b shift altgr + +# evdev 28 (0x1c), QKeyCode "ret", number 0x1c +Return 0x1c + +# evdev 29 (0x1d), QKeyCode "ctrl", number 0x1d +Control_L 0x1d + +# evdev 30 (0x1e), QKeyCode "a", number 0x1e +a 0x1e +A 0x1e shift +ordfeminine 0x1e altgr +masculine 0x1e shift altgr + +# evdev 31 (0x1f), QKeyCode "s", number 0x1f +s 0x1f +S 0x1f shift +ssharp 0x1f altgr +section 0x1f shift altgr + +# evdev 32 (0x20), QKeyCode "d", number 0x20 +d 0x20 +D 0x20 shift +eth 0x20 altgr +ETH 0x20 shift altgr + +# evdev 33 (0x21), QKeyCode "f", number 0x21 +f 0x21 +F 0x21 shift +dstroke 0x21 altgr +ordfeminine 0x21 shift altgr + +# evdev 34 (0x22), QKeyCode "g", number 0x22 +g 0x22 +G 0x22 shift +eng 0x22 altgr +ENG 0x22 shift altgr + +# evdev 35 (0x23), QKeyCode "h", number 0x23 +h 0x23 +H 0x23 shift +hstroke 0x23 altgr +Hstroke 0x23 shift altgr + +# evdev 36 (0x24), QKeyCode "j", number 0x24 +j 0x24 +J 0x24 shift +dead_hook 0x24 altgr +dead_horn 0x24 shift altgr + +# evdev 37 (0x25), QKeyCode "k", number 0x25 +k 0x25 +K 0x25 shift +kra 0x25 altgr +ampersand 0x25 shift altgr + +# evdev 38 (0x26), QKeyCode "l", number 0x26 +l 0x26 +L 0x26 shift +lstroke 0x26 altgr +Lstroke 0x26 shift altgr + +# evdev 39 (0x27), QKeyCode "semicolon", number 0x27 +oslash 0x27 +Oslash 0x27 shift +dead_acute 0x27 altgr +dead_doubleacute 0x27 shift altgr + +# evdev 40 (0x28), QKeyCode "apostrophe", number 0x28 +ae 0x28 +AE 0x28 shift +dead_circumflex 0x28 altgr +dead_caron 0x28 shift altgr + +# evdev 41 (0x29), QKeyCode "grave_accent", number 0x29 +bar 0x29 +section 0x29 shift +brokenbar 0x29 altgr +paragraph 0x29 shift altgr + +# evdev 42 (0x2a), QKeyCode "shift", number 0x2a +Shift_L 0x2a + +# evdev 43 (0x2b), QKeyCode "backslash", number 0x2b +apostrophe 0x2b +asterisk 0x2b shift +dead_doubleacute 0x2b altgr +multiply 0x2b shift altgr + +# evdev 44 (0x2c), QKeyCode "z", number 0x2c +z 0x2c +Z 0x2c shift +guillemotleft 0x2c altgr +less 0x2c shift altgr + +# evdev 45 (0x2d), QKeyCode "x", number 0x2d +x 0x2d +X 0x2d shift +guillemotright 0x2d altgr +greater 0x2d shift altgr + +# evdev 46 (0x2e), QKeyCode "c", number 0x2e +c 0x2e +C 0x2e shift +copyright 0x2e altgr + +# evdev 47 (0x2f), QKeyCode "v", number 0x2f +v 0x2f +V 0x2f shift +leftdoublequotemark 0x2f altgr +leftsinglequotemark 0x2f shift altgr + +# evdev 48 (0x30), QKeyCode "b", number 0x30 +b 0x30 +B 0x30 shift +rightdoublequotemark 0x30 altgr +rightsinglequotemark 0x30 shift altgr + +# evdev 49 (0x31), QKeyCode "n", number 0x31 +n 0x31 +N 0x31 shift + +# evdev 50 (0x32), QKeyCode "m", number 0x32 +m 0x32 +M 0x32 shift +mu 0x32 altgr +masculine 0x32 shift altgr + +# evdev 51 (0x33), QKeyCode "comma", number 0x33 +comma 0x33 +semicolon 0x33 shift +dead_cedilla 0x33 altgr +dead_ogonek 0x33 shift altgr + +# evdev 52 (0x34), QKeyCode "dot", number 0x34 +period 0x34 +colon 0x34 shift +ellipsis 0x34 altgr +periodcentered 0x34 shift altgr + +# evdev 53 (0x35), QKeyCode "slash", number 0x35 +minus 0x35 +underscore 0x35 shift +endash 0x35 altgr +emdash 0x35 shift altgr + +# evdev 54 (0x36), QKeyCode "shift_r", number 0x36 +Shift_R 0x36 + +# evdev 55 (0x37), QKeyCode "kp_multiply", number 0x37 +KP_Multiply 0x37 +U22C5 0x37 shift +0x010000d7 0x37 altgr +VoidSymbol 0x37 shift altgr + +# evdev 56 (0x38), QKeyCode "alt", number 0x38 +Alt_L 0x38 +Meta_L 0x38 shift + +# evdev 57 (0x39), QKeyCode "spc", number 0x39 +space 0x39 +nobreakspace 0x39 altgr +U202F 0x39 shift altgr + +# evdev 58 (0x3a), QKeyCode "caps_lock", number 0x3a +Caps_Lock 0x3a + +# evdev 59 (0x3b), QKeyCode "f1", number 0x3b +F1 0x3b + +# evdev 60 (0x3c), QKeyCode "f2", number 0x3c +F2 0x3c + +# evdev 61 (0x3d), QKeyCode "f3", number 0x3d +F3 0x3d + +# evdev 62 (0x3e), QKeyCode "f4", number 0x3e +F4 0x3e + +# evdev 63 (0x3f), QKeyCode "f5", number 0x3f +F5 0x3f + +# evdev 64 (0x40), QKeyCode "f6", number 0x40 +F6 0x40 + +# evdev 65 (0x41), QKeyCode "f7", number 0x41 +F7 0x41 + +# evdev 66 (0x42), QKeyCode "f8", number 0x42 +F8 0x42 + +# evdev 67 (0x43), QKeyCode "f9", number 0x43 +F9 0x43 + +# evdev 68 (0x44), QKeyCode "f10", number 0x44 +F10 0x44 + +# evdev 69 (0x45), QKeyCode "num_lock", number 0x45 +Num_Lock 0x45 + +# evdev 70 (0x46), QKeyCode "scroll_lock", number 0x46 +Scroll_Lock 0x46 + +# evdev 71 (0x47), QKeyCode "kp_7", number 0x47 +KP_Home 0x47 +KP_7 0x47 numlock + +# evdev 72 (0x48), QKeyCode "kp_8", number 0x48 +KP_Up 0x48 +KP_8 0x48 numlock + +# evdev 73 (0x49), QKeyCode "kp_9", number 0x49 +KP_Prior 0x49 +KP_9 0x49 numlock + +# evdev 74 (0x4a), QKeyCode "kp_subtract", number 0x4a +KP_Subtract 0x4a +U2212 0x4a shift +U2212 0x4a altgr +VoidSymbol 0x4a shift altgr + +# evdev 75 (0x4b), QKeyCode "kp_4", number 0x4b +KP_Left 0x4b +KP_4 0x4b numlock + +# evdev 76 (0x4c), QKeyCode "kp_5", number 0x4c +KP_Begin 0x4c +KP_5 0x4c numlock + +# evdev 77 (0x4d), QKeyCode "kp_6", number 0x4d +KP_Right 0x4d +KP_6 0x4d numlock + +# evdev 78 (0x4e), QKeyCode "kp_add", number 0x4e +KP_Add 0x4e +0x0100002b 0x4e shift +0x0100002b 0x4e altgr +VoidSymbol 0x4e shift altgr + +# evdev 79 (0x4f), QKeyCode "kp_1", number 0x4f +KP_End 0x4f +KP_1 0x4f numlock + +# evdev 80 (0x50), QKeyCode "kp_2", number 0x50 +KP_Down 0x50 +KP_2 0x50 numlock + +# evdev 81 (0x51), QKeyCode "kp_3", number 0x51 +KP_Next 0x51 +KP_3 0x51 numlock + +# evdev 82 (0x52), QKeyCode "kp_0", number 0x52 +KP_Insert 0x52 +KP_0 0x52 numlock + +# evdev 83 (0x53), QKeyCode "kp_decimal", number 0x53 +KP_Delete 0x53 +KP_Separator 0x53 numlock + +# evdev 84 (0x54): no evdev -> QKeyCode mapping (xkb keysym ISO_Level3_Shift) + +# evdev 85 (0x55): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 86 (0x56), QKeyCode "less", number 0x56 +less 0x56 +greater 0x56 shift +onehalf 0x56 altgr +threequarters 0x56 shift altgr + +# evdev 87 (0x57), QKeyCode "f11", number 0x57 +F11 0x57 + +# evdev 88 (0x58), QKeyCode "f12", number 0x58 +F12 0x58 + +# evdev 89 (0x59), QKeyCode "ro", number 0x73 + +# evdev 90 (0x5a): no evdev -> QKeyCode mapping (xkb keysym Katakana) + +# evdev 91 (0x5b), QKeyCode "hiragana", number 0x77 +Hiragana 0x77 + +# evdev 92 (0x5c), QKeyCode "henkan", number 0x79 +Henkan_Mode 0x79 + +# evdev 93 (0x5d), QKeyCode "katakanahiragana", number 0x70 +Hiragana_Katakana 0x70 + +# evdev 94 (0x5e), QKeyCode "muhenkan", number 0x7b +Muhenkan 0x7b + +# evdev 95 (0x5f): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 96 (0x60), QKeyCode "kp_enter", number 0x9c +KP_Enter 0x9c + +# evdev 97 (0x61), QKeyCode "ctrl_r", number 0x9d +Control_R 0x9d + +# evdev 98 (0x62), QKeyCode "kp_divide", number 0xb5 +KP_Divide 0xb5 +U2215 0xb5 shift +0x010000f7 0xb5 altgr +VoidSymbol 0xb5 shift altgr + +# evdev 99 (0x63), QKeyCode "sysrq", number 0x54 +Print 0x54 + +# evdev 100 (0x64), QKeyCode "alt_r", number 0xb8 +ISO_Level3_Shift 0xb8 + +# evdev 101 (0x65), QKeyCode "lf", number 0x5b +Linefeed 0x5b + +# evdev 102 (0x66), QKeyCode "home", number 0xc7 +Home 0xc7 + +# evdev 103 (0x67), QKeyCode "up", number 0xc8 +Up 0xc8 + +# evdev 104 (0x68), QKeyCode "pgup", number 0xc9 +Prior 0xc9 + +# evdev 105 (0x69), QKeyCode "left", number 0xcb +Left 0xcb + +# evdev 106 (0x6a), QKeyCode "right", number 0xcd +Right 0xcd + +# evdev 107 (0x6b), QKeyCode "end", number 0xcf +End 0xcf + +# evdev 108 (0x6c), QKeyCode "down", number 0xd0 +Down 0xd0 + +# evdev 109 (0x6d), QKeyCode "pgdn", number 0xd1 +Next 0xd1 + +# evdev 110 (0x6e), QKeyCode "insert", number 0xd2 +Insert 0xd2 + +# evdev 111 (0x6f), QKeyCode "delete", number 0xd3 +Delete 0xd3 + +# evdev 112 (0x70): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 113 (0x71), QKeyCode "audiomute", number 0xa0 +XF86AudioMute 0xa0 + +# evdev 114 (0x72), QKeyCode "volumedown", number 0xae +XF86AudioLowerVolume 0xae + +# evdev 115 (0x73), QKeyCode "volumeup", number 0xb0 +XF86AudioRaiseVolume 0xb0 + +# evdev 116 (0x74), QKeyCode "power", number 0xde +XF86PowerOff 0xde + +# evdev 117 (0x75), QKeyCode "kp_equals", number 0x59 +KP_Equal 0x59 + +# evdev 118 (0x76): no evdev -> QKeyCode mapping (xkb keysym plusminus) + +# evdev 119 (0x77), QKeyCode "pause", number 0xc6 +Pause 0xc6 + +# evdev 120 (0x78): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchA) + +# evdev 121 (0x79), QKeyCode "kp_comma", number 0x7e +KP_Decimal 0x7e + +# evdev 122 (0x7a): no evdev -> QKeyCode mapping (xkb keysym Hangul) + +# evdev 123 (0x7b): no evdev -> QKeyCode mapping (xkb keysym Hangul_Hanja) + +# evdev 124 (0x7c), QKeyCode "yen", number 0x7d + +# evdev 125 (0x7d), QKeyCode "meta_l", number 0xdb +Super_L 0xdb + +# evdev 126 (0x7e), QKeyCode "meta_r", number 0xdc +Super_R 0xdc + +# evdev 127 (0x7f), QKeyCode "compose", number 0xdd +Menu 0xdd + +# evdev 128 (0x80), QKeyCode "stop", number 0xe8 +Cancel 0xe8 + +# evdev 129 (0x81), QKeyCode "again", number 0x85 +Redo 0x85 + +# evdev 130 (0x82), QKeyCode "props", number 0x86 +SunProps 0x86 + +# evdev 131 (0x83), QKeyCode "undo", number 0x87 +Undo 0x87 + +# evdev 132 (0x84), QKeyCode "front", number 0x8c +SunFront 0x8c + +# evdev 133 (0x85), QKeyCode "copy", number 0xf8 +XF86Copy 0xf8 + +# evdev 134 (0x86), QKeyCode "open", number 0x64 +XF86Open 0x64 + +# evdev 135 (0x87), QKeyCode "paste", number 0x65 +XF86Paste 0x65 + +# evdev 136 (0x88), QKeyCode "find", number 0xc1 +Find 0xc1 + +# evdev 137 (0x89), QKeyCode "cut", number 0xbc +XF86Cut 0xbc + +# evdev 138 (0x8a), QKeyCode "help", number 0xf5 +Help 0xf5 + +# evdev 139 (0x8b), QKeyCode "menu", number 0x9e +XF86MenuKB 0x9e + +# evdev 140 (0x8c), QKeyCode "calculator", number 0xa1 +XF86Calculator 0xa1 + +# evdev 141 (0x8d): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 142 (0x8e), QKeyCode "sleep", number 0xdf +XF86Sleep 0xdf + +# evdev 143 (0x8f), QKeyCode "wake", number 0xe3 +XF86WakeUp 0xe3 + +# evdev 144 (0x90): no evdev -> QKeyCode mapping (xkb keysym XF86Explorer) + +# evdev 145 (0x91): no evdev -> QKeyCode mapping (xkb keysym XF86Send) + +# evdev 146 (0x92): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 147 (0x93): no evdev -> QKeyCode mapping (xkb keysym XF86Xfer) + +# evdev 148 (0x94): no evdev -> QKeyCode mapping (xkb keysym XF86Launch1) + +# evdev 149 (0x95): no evdev -> QKeyCode mapping (xkb keysym XF86Launch2) + +# evdev 150 (0x96): no evdev -> QKeyCode mapping (xkb keysym XF86WWW) + +# evdev 151 (0x97): no evdev -> QKeyCode mapping (xkb keysym XF86DOS) + +# evdev 152 (0x98): no evdev -> QKeyCode mapping (xkb keysym XF86ScreenSaver) + +# evdev 153 (0x99): no evdev -> QKeyCode mapping (xkb keysym XF86RotateWindows) + +# evdev 154 (0x9a): no evdev -> QKeyCode mapping (xkb keysym XF86TaskPane) + +# evdev 155 (0x9b), QKeyCode "mail", number 0xec +XF86Mail 0xec + +# evdev 156 (0x9c), QKeyCode "ac_bookmarks", number 0xe6 +XF86Favorites 0xe6 + +# evdev 157 (0x9d), QKeyCode "computer", number 0xeb +XF86MyComputer 0xeb + +# evdev 158 (0x9e), QKeyCode "ac_back", number 0xea +XF86Back 0xea + +# evdev 159 (0x9f), QKeyCode "ac_forward", number 0xe9 +XF86Forward 0xe9 + +# evdev 160 (0xa0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 161 (0xa1): no evdev -> QKeyCode mapping (xkb keysym XF86Eject) + +# evdev 162 (0xa2): no evdev -> QKeyCode mapping (xkb keysym XF86Eject) + +# evdev 163 (0xa3), QKeyCode "audionext", number 0x99 +XF86AudioNext 0x99 + +# evdev 164 (0xa4), QKeyCode "audioplay", number 0xa2 +XF86AudioPlay 0xa2 +XF86AudioPause 0xa2 shift + +# evdev 165 (0xa5), QKeyCode "audioprev", number 0x90 +XF86AudioPrev 0x90 + +# evdev 166 (0xa6), QKeyCode "audiostop", number 0xa4 +XF86AudioStop 0xa4 +XF86Eject 0xa4 shift + +# evdev 167 (0xa7): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRecord) + +# evdev 168 (0xa8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRewind) + +# evdev 169 (0xa9): no evdev -> QKeyCode mapping (xkb keysym XF86Phone) + +# evdev 170 (0xaa): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 171 (0xab): no evdev -> QKeyCode mapping (xkb keysym XF86Tools) + +# evdev 172 (0xac), QKeyCode "ac_home", number 0xb2 +XF86HomePage 0xb2 + +# evdev 173 (0xad), QKeyCode "ac_refresh", number 0xe7 +XF86Reload 0xe7 + +# evdev 174 (0xae): no evdev -> QKeyCode mapping (xkb keysym XF86Close) + +# evdev 175 (0xaf): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 176 (0xb0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 177 (0xb1): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollUp) + +# evdev 178 (0xb2): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollDown) + +# evdev 179 (0xb3): no evdev -> QKeyCode mapping (xkb keysym parenleft) + +# evdev 180 (0xb4): no evdev -> QKeyCode mapping (xkb keysym parenright) + +# evdev 181 (0xb5): no evdev -> QKeyCode mapping (xkb keysym XF86New) + +# evdev 182 (0xb6): no evdev -> QKeyCode mapping (xkb keysym Redo) + +# evdev 183 (0xb7): no evdev -> QKeyCode mapping (xkb keysym XF86Tools) + +# evdev 184 (0xb8): no evdev -> QKeyCode mapping (xkb keysym XF86Launch5) + +# evdev 185 (0xb9): no evdev -> QKeyCode mapping (xkb keysym XF86Launch6) + +# evdev 186 (0xba): no evdev -> QKeyCode mapping (xkb keysym XF86Launch7) + +# evdev 187 (0xbb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch8) + +# evdev 188 (0xbc): no evdev -> QKeyCode mapping (xkb keysym XF86Launch9) + +# evdev 189 (0xbd): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 190 (0xbe): no evdev -> QKeyCode mapping (xkb keysym XF86AudioMicMute) + +# evdev 191 (0xbf): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadToggle) + +# evdev 192 (0xc0): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOn) + +# evdev 193 (0xc1): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOff) + +# evdev 194 (0xc2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 195 (0xc3): no evdev -> QKeyCode mapping (xkb keysym Mode_switch) + +# evdev 196 (0xc4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 197 (0xc5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 198 (0xc6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 199 (0xc7): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 200 (0xc8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay) + +# evdev 201 (0xc9): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPause) + +# evdev 202 (0xca): no evdev -> QKeyCode mapping (xkb keysym XF86Launch3) + +# evdev 203 (0xcb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch4) + +# evdev 204 (0xcc): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchB) + +# evdev 205 (0xcd): no evdev -> QKeyCode mapping (xkb keysym XF86Suspend) + +# evdev 206 (0xce): no evdev -> QKeyCode mapping (xkb keysym XF86Close) + +# evdev 207 (0xcf): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay) + +# evdev 208 (0xd0): no evdev -> QKeyCode mapping (xkb keysym XF86AudioForward) + +# evdev 209 (0xd1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 210 (0xd2): no evdev -> QKeyCode mapping (xkb keysym Print) + +# evdev 211 (0xd3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 212 (0xd4): no evdev -> QKeyCode mapping (xkb keysym XF86WebCam) + +# evdev 213 (0xd5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 214 (0xd6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 215 (0xd7): no evdev -> QKeyCode mapping (xkb keysym XF86Mail) + +# evdev 216 (0xd8): no evdev -> QKeyCode mapping (xkb keysym XF86Messenger) + +# evdev 217 (0xd9): no evdev -> QKeyCode mapping (xkb keysym XF86Search) + +# evdev 218 (0xda): no evdev -> QKeyCode mapping (xkb keysym XF86Go) + +# evdev 219 (0xdb): no evdev -> QKeyCode mapping (xkb keysym XF86Finance) + +# evdev 220 (0xdc): no evdev -> QKeyCode mapping (xkb keysym XF86Game) + +# evdev 221 (0xdd): no evdev -> QKeyCode mapping (xkb keysym XF86Shop) + +# evdev 222 (0xde): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 223 (0xdf): no evdev -> QKeyCode mapping (xkb keysym Cancel) + +# evdev 224 (0xe0): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessDown) + +# evdev 225 (0xe1): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessUp) + +# evdev 226 (0xe2), QKeyCode "mediaselect", number 0xed +XF86AudioMedia 0xed + +# evdev 227 (0xe3): no evdev -> QKeyCode mapping (xkb keysym XF86Display) + +# evdev 228 (0xe4): no evdev -> QKeyCode mapping (xkb keysym XF86KbdLightOnOff) + +# evdev 229 (0xe5): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessDown) + +# evdev 230 (0xe6): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessUp) + +# evdev 231 (0xe7): no evdev -> QKeyCode mapping (xkb keysym XF86Send) + +# evdev 232 (0xe8): no evdev -> QKeyCode mapping (xkb keysym XF86Reply) + +# evdev 233 (0xe9): no evdev -> QKeyCode mapping (xkb keysym XF86MailForward) + +# evdev 234 (0xea): no evdev -> QKeyCode mapping (xkb keysym XF86Save) + +# evdev 235 (0xeb): no evdev -> QKeyCode mapping (xkb keysym XF86Documents) + +# evdev 236 (0xec): no evdev -> QKeyCode mapping (xkb keysym XF86Battery) + +# evdev 237 (0xed): no evdev -> QKeyCode mapping (xkb keysym XF86Bluetooth) + +# evdev 238 (0xee): no evdev -> QKeyCode mapping (xkb keysym XF86WLAN) + +# evdev 239 (0xef): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 240 (0xf0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 241 (0xf1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 242 (0xf2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 243 (0xf3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 244 (0xf4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 245 (0xf5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 246 (0xf6): no evdev -> QKeyCode mapping (xkb keysym 0x00408160) + +# evdev 247 (0xf7): no evdev -> QKeyCode mapping (xkb keysym 0x00408270) + +# +# quirks section start +# +# Sometimes multiple keysyms map to the same keycodes. +# The keycode -> keysym lookup finds only one of the +# keysyms. So append them here. +# + +Print 0x54 +Sys_Req 0x54 +Execute 0x54 +KP_Decimal 0x53 numlock +KP_Separator 0x53 numlock +Alt_R 0xb8 +ISO_Level3_Shift 0xb8 +Mode_switch 0xb8 + +# quirks section end diff --git a/app/src/main/assets/roms/keymaps/pl b/app/src/main/assets/roms/keymaps/pl new file mode 100644 index 0000000..30d93ca --- /dev/null +++ b/app/src/main/assets/roms/keymaps/pl @@ -0,0 +1,847 @@ +# +# generated by qemu-keymap +# model : pc105 +# layout : pl +# variant : - +# options : - + +# name: "Polish" + +# modifiers +# 0: Shift +# 1: Lock +# 2: Control +# 3: Mod1 +# 4: Mod2 +# 5: Mod3 +# 6: Mod4 +# 7: Mod5 +# 8: NumLock +# 9: Alt +# 10: LevelThree +# 11: LAlt +# 12: RAlt +# 13: RControl +# 14: LControl +# 15: ScrollLock +# 16: LevelFive +# 17: AltGr +# 18: Meta +# 19: Super +# 20: Hyper + +# evdev 1 (0x1), QKeyCode "esc", number 0x1 +Escape 0x01 + +# evdev 2 (0x2), QKeyCode "1", number 0x2 +1 0x02 +exclam 0x02 shift +notequal 0x02 altgr +exclamdown 0x02 shift altgr + +# evdev 3 (0x3), QKeyCode "2", number 0x3 +2 0x03 +at 0x03 shift +twosuperior 0x03 altgr +questiondown 0x03 shift altgr + +# evdev 4 (0x4), QKeyCode "3", number 0x4 +3 0x04 +numbersign 0x04 shift +threesuperior 0x04 altgr +sterling 0x04 shift altgr + +# evdev 5 (0x5), QKeyCode "4", number 0x5 +4 0x05 +dollar 0x05 shift +cent 0x05 altgr +onequarter 0x05 shift altgr + +# evdev 6 (0x6), QKeyCode "5", number 0x6 +5 0x06 +percent 0x06 shift +EuroSign 0x06 altgr +U2030 0x06 shift altgr + +# evdev 7 (0x7), QKeyCode "6", number 0x7 +6 0x07 +asciicircum 0x07 shift +onehalf 0x07 altgr +logicaland 0x07 shift altgr + +# evdev 8 (0x8), QKeyCode "7", number 0x8 +7 0x08 +ampersand 0x08 shift +section 0x08 altgr +approxeq 0x08 shift altgr + +# evdev 9 (0x9), QKeyCode "8", number 0x9 +8 0x09 +asterisk 0x09 shift +periodcentered 0x09 altgr +threequarters 0x09 shift altgr + +# evdev 10 (0xa), QKeyCode "9", number 0xa +9 0x0a +parenleft 0x0a shift +guillemotleft 0x0a altgr +plusminus 0x0a shift altgr + +# evdev 11 (0xb), QKeyCode "0", number 0xb +0 0x0b +parenright 0x0b shift +guillemotright 0x0b altgr +degree 0x0b shift altgr + +# evdev 12 (0xc), QKeyCode "minus", number 0xc +minus 0x0c +underscore 0x0c shift +endash 0x0c altgr +emdash 0x0c shift altgr + +# evdev 13 (0xd), QKeyCode "equal", number 0xd +equal 0x0d +plus 0x0d shift +dead_cedilla 0x0d altgr +dead_ogonek 0x0d shift altgr + +# evdev 14 (0xe), QKeyCode "backspace", number 0xe +BackSpace 0x0e + +# evdev 15 (0xf), QKeyCode "tab", number 0xf +Tab 0x0f +ISO_Left_Tab 0x0f shift + +# evdev 16 (0x10), QKeyCode "q", number 0x10 +q 0x10 +Q 0x10 shift +Greek_pi 0x10 altgr +Greek_OMEGA 0x10 shift altgr + +# evdev 17 (0x11), QKeyCode "w", number 0x11 +w 0x11 +W 0x11 shift +oe 0x11 altgr +OE 0x11 shift altgr + +# evdev 18 (0x12), QKeyCode "e", number 0x12 +e 0x12 +E 0x12 shift +eogonek 0x12 altgr +Eogonek 0x12 shift altgr + +# evdev 19 (0x13), QKeyCode "r", number 0x13 +r 0x13 +R 0x13 shift +copyright 0x13 altgr +registered 0x13 shift altgr + +# evdev 20 (0x14), QKeyCode "t", number 0x14 +t 0x14 +T 0x14 shift +ssharp 0x14 altgr +trademark 0x14 shift altgr + +# evdev 21 (0x15), QKeyCode "y", number 0x15 +y 0x15 +Y 0x15 shift +leftarrow 0x15 altgr +yen 0x15 shift altgr + +# evdev 22 (0x16), QKeyCode "u", number 0x16 +u 0x16 +U 0x16 shift +downarrow 0x16 altgr +uparrow 0x16 shift altgr + +# evdev 23 (0x17), QKeyCode "i", number 0x17 +i 0x17 +I 0x17 shift +rightarrow 0x17 altgr +U2194 0x17 shift altgr + +# evdev 24 (0x18), QKeyCode "o", number 0x18 +o 0x18 +O 0x18 shift +oacute 0x18 altgr +Oacute 0x18 shift altgr + +# evdev 25 (0x19), QKeyCode "p", number 0x19 +p 0x19 +P 0x19 shift +thorn 0x19 altgr +THORN 0x19 shift altgr + +# evdev 26 (0x1a), QKeyCode "bracket_left", number 0x1a +bracketleft 0x1a +braceleft 0x1a shift +dead_diaeresis 0x1a altgr +dead_abovering 0x1a shift altgr + +# evdev 27 (0x1b), QKeyCode "bracket_right", number 0x1b +bracketright 0x1b +braceright 0x1b shift +dead_tilde 0x1b altgr +dead_macron 0x1b shift altgr + +# evdev 28 (0x1c), QKeyCode "ret", number 0x1c +Return 0x1c + +# evdev 29 (0x1d), QKeyCode "ctrl", number 0x1d +Control_L 0x1d + +# evdev 30 (0x1e), QKeyCode "a", number 0x1e +a 0x1e +A 0x1e shift +aogonek 0x1e altgr +Aogonek 0x1e shift altgr + +# evdev 31 (0x1f), QKeyCode "s", number 0x1f +s 0x1f +S 0x1f shift +sacute 0x1f altgr +Sacute 0x1f shift altgr + +# evdev 32 (0x20), QKeyCode "d", number 0x20 +d 0x20 +D 0x20 shift +eth 0x20 altgr +ETH 0x20 shift altgr + +# evdev 33 (0x21), QKeyCode "f", number 0x21 +f 0x21 +F 0x21 shift +ae 0x21 altgr +AE 0x21 shift altgr + +# evdev 34 (0x22), QKeyCode "g", number 0x22 +g 0x22 +G 0x22 shift +eng 0x22 altgr +ENG 0x22 shift altgr + +# evdev 35 (0x23), QKeyCode "h", number 0x23 +h 0x23 +H 0x23 shift +rightsinglequotemark 0x23 altgr +U2022 0x23 shift altgr + +# evdev 36 (0x24), QKeyCode "j", number 0x24 +j 0x24 +J 0x24 shift +schwa 0x24 altgr +SCHWA 0x24 shift altgr + +# evdev 37 (0x25), QKeyCode "k", number 0x25 +k 0x25 +K 0x25 shift +ellipsis 0x25 altgr +dead_stroke 0x25 shift altgr + +# evdev 38 (0x26), QKeyCode "l", number 0x26 +l 0x26 +L 0x26 shift +lstroke 0x26 altgr +Lstroke 0x26 shift altgr + +# evdev 39 (0x27), QKeyCode "semicolon", number 0x27 +semicolon 0x27 +colon 0x27 shift +dead_acute 0x27 altgr +dead_doubleacute 0x27 shift altgr + +# evdev 40 (0x28), QKeyCode "apostrophe", number 0x28 +apostrophe 0x28 +quotedbl 0x28 shift +dead_circumflex 0x28 altgr +dead_caron 0x28 shift altgr + +# evdev 41 (0x29), QKeyCode "grave_accent", number 0x29 +grave 0x29 +asciitilde 0x29 shift +notsign 0x29 altgr +logicalor 0x29 shift altgr + +# evdev 42 (0x2a), QKeyCode "shift", number 0x2a +Shift_L 0x2a + +# evdev 43 (0x2b), QKeyCode "backslash", number 0x2b +backslash 0x2b +bar 0x2b shift +dead_grave 0x2b altgr +dead_breve 0x2b shift altgr + +# evdev 44 (0x2c), QKeyCode "z", number 0x2c +z 0x2c +Z 0x2c shift +zabovedot 0x2c altgr +Zabovedot 0x2c shift altgr + +# evdev 45 (0x2d), QKeyCode "x", number 0x2d +x 0x2d +X 0x2d shift +zacute 0x2d altgr +Zacute 0x2d shift altgr + +# evdev 46 (0x2e), QKeyCode "c", number 0x2e +c 0x2e +C 0x2e shift +cacute 0x2e altgr +Cacute 0x2e shift altgr + +# evdev 47 (0x2f), QKeyCode "v", number 0x2f +v 0x2f +V 0x2f shift +doublelowquotemark 0x2f altgr +leftsinglequotemark 0x2f shift altgr + +# evdev 48 (0x30), QKeyCode "b", number 0x30 +b 0x30 +B 0x30 shift +rightdoublequotemark 0x30 altgr +leftdoublequotemark 0x30 shift altgr + +# evdev 49 (0x31), QKeyCode "n", number 0x31 +n 0x31 +N 0x31 shift +nacute 0x31 altgr +Nacute 0x31 shift altgr + +# evdev 50 (0x32), QKeyCode "m", number 0x32 +m 0x32 +M 0x32 shift +mu 0x32 altgr +infinity 0x32 shift altgr + +# evdev 51 (0x33), QKeyCode "comma", number 0x33 +comma 0x33 +less 0x33 shift +lessthanequal 0x33 altgr +multiply 0x33 shift altgr + +# evdev 52 (0x34), QKeyCode "dot", number 0x34 +period 0x34 +greater 0x34 shift +greaterthanequal 0x34 altgr +division 0x34 shift altgr + +# evdev 53 (0x35), QKeyCode "slash", number 0x35 +slash 0x35 +question 0x35 shift +dead_belowdot 0x35 altgr +dead_abovedot 0x35 shift altgr + +# evdev 54 (0x36), QKeyCode "shift_r", number 0x36 +Shift_R 0x36 + +# evdev 55 (0x37), QKeyCode "kp_multiply", number 0x37 +KP_Multiply 0x37 + +# evdev 56 (0x38), QKeyCode "alt", number 0x38 +Alt_L 0x38 +Meta_L 0x38 shift + +# evdev 57 (0x39), QKeyCode "spc", number 0x39 +space 0x39 +nobreakspace 0x39 altgr + +# evdev 58 (0x3a), QKeyCode "caps_lock", number 0x3a +Caps_Lock 0x3a + +# evdev 59 (0x3b), QKeyCode "f1", number 0x3b +F1 0x3b + +# evdev 60 (0x3c), QKeyCode "f2", number 0x3c +F2 0x3c + +# evdev 61 (0x3d), QKeyCode "f3", number 0x3d +F3 0x3d + +# evdev 62 (0x3e), QKeyCode "f4", number 0x3e +F4 0x3e + +# evdev 63 (0x3f), QKeyCode "f5", number 0x3f +F5 0x3f + +# evdev 64 (0x40), QKeyCode "f6", number 0x40 +F6 0x40 + +# evdev 65 (0x41), QKeyCode "f7", number 0x41 +F7 0x41 + +# evdev 66 (0x42), QKeyCode "f8", number 0x42 +F8 0x42 + +# evdev 67 (0x43), QKeyCode "f9", number 0x43 +F9 0x43 + +# evdev 68 (0x44), QKeyCode "f10", number 0x44 +F10 0x44 + +# evdev 69 (0x45), QKeyCode "num_lock", number 0x45 +Num_Lock 0x45 + +# evdev 70 (0x46), QKeyCode "scroll_lock", number 0x46 +Scroll_Lock 0x46 + +# evdev 71 (0x47), QKeyCode "kp_7", number 0x47 +KP_Home 0x47 +KP_7 0x47 numlock + +# evdev 72 (0x48), QKeyCode "kp_8", number 0x48 +KP_Up 0x48 +KP_8 0x48 numlock + +# evdev 73 (0x49), QKeyCode "kp_9", number 0x49 +KP_Prior 0x49 +KP_9 0x49 numlock + +# evdev 74 (0x4a), QKeyCode "kp_subtract", number 0x4a +KP_Subtract 0x4a + +# evdev 75 (0x4b), QKeyCode "kp_4", number 0x4b +KP_Left 0x4b +KP_4 0x4b numlock + +# evdev 76 (0x4c), QKeyCode "kp_5", number 0x4c +KP_Begin 0x4c +KP_5 0x4c numlock + +# evdev 77 (0x4d), QKeyCode "kp_6", number 0x4d +KP_Right 0x4d +KP_6 0x4d numlock + +# evdev 78 (0x4e), QKeyCode "kp_add", number 0x4e +KP_Add 0x4e + +# evdev 79 (0x4f), QKeyCode "kp_1", number 0x4f +KP_End 0x4f +KP_1 0x4f numlock + +# evdev 80 (0x50), QKeyCode "kp_2", number 0x50 +KP_Down 0x50 +KP_2 0x50 numlock + +# evdev 81 (0x51), QKeyCode "kp_3", number 0x51 +KP_Next 0x51 +KP_3 0x51 numlock + +# evdev 82 (0x52), QKeyCode "kp_0", number 0x52 +KP_Insert 0x52 +KP_0 0x52 numlock + +# evdev 83 (0x53), QKeyCode "kp_decimal", number 0x53 +KP_Delete 0x53 +KP_Separator 0x53 numlock + +# evdev 84 (0x54): no evdev -> QKeyCode mapping (xkb keysym ISO_Level3_Shift) + +# evdev 85 (0x55): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 86 (0x56), QKeyCode "less", number 0x56 +less 0x56 +greater 0x56 shift +bar 0x56 altgr +brokenbar 0x56 shift altgr + +# evdev 87 (0x57), QKeyCode "f11", number 0x57 +F11 0x57 + +# evdev 88 (0x58), QKeyCode "f12", number 0x58 +F12 0x58 + +# evdev 89 (0x59), QKeyCode "ro", number 0x73 + +# evdev 90 (0x5a): no evdev -> QKeyCode mapping (xkb keysym Katakana) + +# evdev 91 (0x5b), QKeyCode "hiragana", number 0x77 +Hiragana 0x77 + +# evdev 92 (0x5c), QKeyCode "henkan", number 0x79 +Henkan_Mode 0x79 + +# evdev 93 (0x5d), QKeyCode "katakanahiragana", number 0x70 +Hiragana_Katakana 0x70 + +# evdev 94 (0x5e), QKeyCode "muhenkan", number 0x7b +Muhenkan 0x7b + +# evdev 95 (0x5f): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 96 (0x60), QKeyCode "kp_enter", number 0x9c +KP_Enter 0x9c + +# evdev 97 (0x61), QKeyCode "ctrl_r", number 0x9d +Control_R 0x9d + +# evdev 98 (0x62), QKeyCode "kp_divide", number 0xb5 +KP_Divide 0xb5 + +# evdev 99 (0x63), QKeyCode "sysrq", number 0x54 +Print 0x54 + +# evdev 100 (0x64), QKeyCode "alt_r", number 0xb8 +ISO_Level3_Shift 0xb8 + +# evdev 101 (0x65), QKeyCode "lf", number 0x5b +Linefeed 0x5b + +# evdev 102 (0x66), QKeyCode "home", number 0xc7 +Home 0xc7 + +# evdev 103 (0x67), QKeyCode "up", number 0xc8 +Up 0xc8 + +# evdev 104 (0x68), QKeyCode "pgup", number 0xc9 +Prior 0xc9 + +# evdev 105 (0x69), QKeyCode "left", number 0xcb +Left 0xcb + +# evdev 106 (0x6a), QKeyCode "right", number 0xcd +Right 0xcd + +# evdev 107 (0x6b), QKeyCode "end", number 0xcf +End 0xcf + +# evdev 108 (0x6c), QKeyCode "down", number 0xd0 +Down 0xd0 + +# evdev 109 (0x6d), QKeyCode "pgdn", number 0xd1 +Next 0xd1 + +# evdev 110 (0x6e), QKeyCode "insert", number 0xd2 +Insert 0xd2 + +# evdev 111 (0x6f), QKeyCode "delete", number 0xd3 +Delete 0xd3 + +# evdev 112 (0x70): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 113 (0x71), QKeyCode "audiomute", number 0xa0 +XF86AudioMute 0xa0 + +# evdev 114 (0x72), QKeyCode "volumedown", number 0xae +XF86AudioLowerVolume 0xae + +# evdev 115 (0x73), QKeyCode "volumeup", number 0xb0 +XF86AudioRaiseVolume 0xb0 + +# evdev 116 (0x74), QKeyCode "power", number 0xde +XF86PowerOff 0xde + +# evdev 117 (0x75), QKeyCode "kp_equals", number 0x59 +KP_Equal 0x59 + +# evdev 118 (0x76): no evdev -> QKeyCode mapping (xkb keysym plusminus) + +# evdev 119 (0x77), QKeyCode "pause", number 0xc6 +Pause 0xc6 + +# evdev 120 (0x78): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchA) + +# evdev 121 (0x79), QKeyCode "kp_comma", number 0x7e +KP_Decimal 0x7e + +# evdev 122 (0x7a): no evdev -> QKeyCode mapping (xkb keysym Hangul) + +# evdev 123 (0x7b): no evdev -> QKeyCode mapping (xkb keysym Hangul_Hanja) + +# evdev 124 (0x7c), QKeyCode "yen", number 0x7d + +# evdev 125 (0x7d), QKeyCode "meta_l", number 0xdb +Super_L 0xdb + +# evdev 126 (0x7e), QKeyCode "meta_r", number 0xdc +Super_R 0xdc + +# evdev 127 (0x7f), QKeyCode "compose", number 0xdd +Menu 0xdd + +# evdev 128 (0x80), QKeyCode "stop", number 0xe8 +Cancel 0xe8 + +# evdev 129 (0x81), QKeyCode "again", number 0x85 +Redo 0x85 + +# evdev 130 (0x82), QKeyCode "props", number 0x86 +SunProps 0x86 + +# evdev 131 (0x83), QKeyCode "undo", number 0x87 +Undo 0x87 + +# evdev 132 (0x84), QKeyCode "front", number 0x8c +SunFront 0x8c + +# evdev 133 (0x85), QKeyCode "copy", number 0xf8 +XF86Copy 0xf8 + +# evdev 134 (0x86), QKeyCode "open", number 0x64 +XF86Open 0x64 + +# evdev 135 (0x87), QKeyCode "paste", number 0x65 +XF86Paste 0x65 + +# evdev 136 (0x88), QKeyCode "find", number 0xc1 +Find 0xc1 + +# evdev 137 (0x89), QKeyCode "cut", number 0xbc +XF86Cut 0xbc + +# evdev 138 (0x8a), QKeyCode "help", number 0xf5 +Help 0xf5 + +# evdev 139 (0x8b), QKeyCode "menu", number 0x9e +XF86MenuKB 0x9e + +# evdev 140 (0x8c), QKeyCode "calculator", number 0xa1 +XF86Calculator 0xa1 + +# evdev 141 (0x8d): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 142 (0x8e), QKeyCode "sleep", number 0xdf +XF86Sleep 0xdf + +# evdev 143 (0x8f), QKeyCode "wake", number 0xe3 +XF86WakeUp 0xe3 + +# evdev 144 (0x90): no evdev -> QKeyCode mapping (xkb keysym XF86Explorer) + +# evdev 145 (0x91): no evdev -> QKeyCode mapping (xkb keysym XF86Send) + +# evdev 146 (0x92): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 147 (0x93): no evdev -> QKeyCode mapping (xkb keysym XF86Xfer) + +# evdev 148 (0x94): no evdev -> QKeyCode mapping (xkb keysym XF86Launch1) + +# evdev 149 (0x95): no evdev -> QKeyCode mapping (xkb keysym XF86Launch2) + +# evdev 150 (0x96): no evdev -> QKeyCode mapping (xkb keysym XF86WWW) + +# evdev 151 (0x97): no evdev -> QKeyCode mapping (xkb keysym XF86DOS) + +# evdev 152 (0x98): no evdev -> QKeyCode mapping (xkb keysym XF86ScreenSaver) + +# evdev 153 (0x99): no evdev -> QKeyCode mapping (xkb keysym XF86RotateWindows) + +# evdev 154 (0x9a): no evdev -> QKeyCode mapping (xkb keysym XF86TaskPane) + +# evdev 155 (0x9b), QKeyCode "mail", number 0xec +XF86Mail 0xec + +# evdev 156 (0x9c), QKeyCode "ac_bookmarks", number 0xe6 +XF86Favorites 0xe6 + +# evdev 157 (0x9d), QKeyCode "computer", number 0xeb +XF86MyComputer 0xeb + +# evdev 158 (0x9e), QKeyCode "ac_back", number 0xea +XF86Back 0xea + +# evdev 159 (0x9f), QKeyCode "ac_forward", number 0xe9 +XF86Forward 0xe9 + +# evdev 160 (0xa0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 161 (0xa1): no evdev -> QKeyCode mapping (xkb keysym XF86Eject) + +# evdev 162 (0xa2): no evdev -> QKeyCode mapping (xkb keysym XF86Eject) + +# evdev 163 (0xa3), QKeyCode "audionext", number 0x99 +XF86AudioNext 0x99 + +# evdev 164 (0xa4), QKeyCode "audioplay", number 0xa2 +XF86AudioPlay 0xa2 +XF86AudioPause 0xa2 shift + +# evdev 165 (0xa5), QKeyCode "audioprev", number 0x90 +XF86AudioPrev 0x90 + +# evdev 166 (0xa6), QKeyCode "audiostop", number 0xa4 +XF86AudioStop 0xa4 +XF86Eject 0xa4 shift + +# evdev 167 (0xa7): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRecord) + +# evdev 168 (0xa8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRewind) + +# evdev 169 (0xa9): no evdev -> QKeyCode mapping (xkb keysym XF86Phone) + +# evdev 170 (0xaa): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 171 (0xab): no evdev -> QKeyCode mapping (xkb keysym XF86Tools) + +# evdev 172 (0xac), QKeyCode "ac_home", number 0xb2 +XF86HomePage 0xb2 + +# evdev 173 (0xad), QKeyCode "ac_refresh", number 0xe7 +XF86Reload 0xe7 + +# evdev 174 (0xae): no evdev -> QKeyCode mapping (xkb keysym XF86Close) + +# evdev 175 (0xaf): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 176 (0xb0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 177 (0xb1): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollUp) + +# evdev 178 (0xb2): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollDown) + +# evdev 179 (0xb3): no evdev -> QKeyCode mapping (xkb keysym parenleft) + +# evdev 180 (0xb4): no evdev -> QKeyCode mapping (xkb keysym parenright) + +# evdev 181 (0xb5): no evdev -> QKeyCode mapping (xkb keysym XF86New) + +# evdev 182 (0xb6): no evdev -> QKeyCode mapping (xkb keysym Redo) + +# evdev 183 (0xb7): no evdev -> QKeyCode mapping (xkb keysym XF86Tools) + +# evdev 184 (0xb8): no evdev -> QKeyCode mapping (xkb keysym XF86Launch5) + +# evdev 185 (0xb9): no evdev -> QKeyCode mapping (xkb keysym XF86Launch6) + +# evdev 186 (0xba): no evdev -> QKeyCode mapping (xkb keysym XF86Launch7) + +# evdev 187 (0xbb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch8) + +# evdev 188 (0xbc): no evdev -> QKeyCode mapping (xkb keysym XF86Launch9) + +# evdev 189 (0xbd): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 190 (0xbe): no evdev -> QKeyCode mapping (xkb keysym XF86AudioMicMute) + +# evdev 191 (0xbf): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadToggle) + +# evdev 192 (0xc0): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOn) + +# evdev 193 (0xc1): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOff) + +# evdev 194 (0xc2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 195 (0xc3): no evdev -> QKeyCode mapping (xkb keysym Mode_switch) + +# evdev 196 (0xc4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 197 (0xc5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 198 (0xc6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 199 (0xc7): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 200 (0xc8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay) + +# evdev 201 (0xc9): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPause) + +# evdev 202 (0xca): no evdev -> QKeyCode mapping (xkb keysym XF86Launch3) + +# evdev 203 (0xcb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch4) + +# evdev 204 (0xcc): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchB) + +# evdev 205 (0xcd): no evdev -> QKeyCode mapping (xkb keysym XF86Suspend) + +# evdev 206 (0xce): no evdev -> QKeyCode mapping (xkb keysym XF86Close) + +# evdev 207 (0xcf): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay) + +# evdev 208 (0xd0): no evdev -> QKeyCode mapping (xkb keysym XF86AudioForward) + +# evdev 209 (0xd1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 210 (0xd2): no evdev -> QKeyCode mapping (xkb keysym Print) + +# evdev 211 (0xd3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 212 (0xd4): no evdev -> QKeyCode mapping (xkb keysym XF86WebCam) + +# evdev 213 (0xd5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 214 (0xd6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 215 (0xd7): no evdev -> QKeyCode mapping (xkb keysym XF86Mail) + +# evdev 216 (0xd8): no evdev -> QKeyCode mapping (xkb keysym XF86Messenger) + +# evdev 217 (0xd9): no evdev -> QKeyCode mapping (xkb keysym XF86Search) + +# evdev 218 (0xda): no evdev -> QKeyCode mapping (xkb keysym XF86Go) + +# evdev 219 (0xdb): no evdev -> QKeyCode mapping (xkb keysym XF86Finance) + +# evdev 220 (0xdc): no evdev -> QKeyCode mapping (xkb keysym XF86Game) + +# evdev 221 (0xdd): no evdev -> QKeyCode mapping (xkb keysym XF86Shop) + +# evdev 222 (0xde): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 223 (0xdf): no evdev -> QKeyCode mapping (xkb keysym Cancel) + +# evdev 224 (0xe0): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessDown) + +# evdev 225 (0xe1): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessUp) + +# evdev 226 (0xe2), QKeyCode "mediaselect", number 0xed +XF86AudioMedia 0xed + +# evdev 227 (0xe3): no evdev -> QKeyCode mapping (xkb keysym XF86Display) + +# evdev 228 (0xe4): no evdev -> QKeyCode mapping (xkb keysym XF86KbdLightOnOff) + +# evdev 229 (0xe5): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessDown) + +# evdev 230 (0xe6): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessUp) + +# evdev 231 (0xe7): no evdev -> QKeyCode mapping (xkb keysym XF86Send) + +# evdev 232 (0xe8): no evdev -> QKeyCode mapping (xkb keysym XF86Reply) + +# evdev 233 (0xe9): no evdev -> QKeyCode mapping (xkb keysym XF86MailForward) + +# evdev 234 (0xea): no evdev -> QKeyCode mapping (xkb keysym XF86Save) + +# evdev 235 (0xeb): no evdev -> QKeyCode mapping (xkb keysym XF86Documents) + +# evdev 236 (0xec): no evdev -> QKeyCode mapping (xkb keysym XF86Battery) + +# evdev 237 (0xed): no evdev -> QKeyCode mapping (xkb keysym XF86Bluetooth) + +# evdev 238 (0xee): no evdev -> QKeyCode mapping (xkb keysym XF86WLAN) + +# evdev 239 (0xef): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 240 (0xf0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 241 (0xf1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 242 (0xf2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 243 (0xf3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 244 (0xf4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 245 (0xf5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 246 (0xf6): no evdev -> QKeyCode mapping (xkb keysym Invalid) + +# evdev 247 (0xf7): no evdev -> QKeyCode mapping (xkb keysym Invalid) + +# +# quirks section start +# +# Sometimes multiple keysyms map to the same keycodes. +# The keycode -> keysym lookup finds only one of the +# keysyms. So append them here. +# + +Print 0x54 +Sys_Req 0x54 +Execute 0x54 +KP_Decimal 0x53 numlock +KP_Separator 0x53 numlock +Alt_R 0xb8 +ISO_Level3_Shift 0xb8 +Mode_switch 0xb8 + +# quirks section end diff --git a/app/src/main/assets/roms/keymaps/pt b/app/src/main/assets/roms/keymaps/pt new file mode 100644 index 0000000..c34d6e3 --- /dev/null +++ b/app/src/main/assets/roms/keymaps/pt @@ -0,0 +1,840 @@ +# +# generated by qemu-keymap +# model : pc105 +# layout : pt +# variant : - +# options : - + +# name: "Portuguese" + +# modifiers +# 0: Shift +# 1: Lock +# 2: Control +# 3: Mod1 +# 4: Mod2 +# 5: Mod3 +# 6: Mod4 +# 7: Mod5 +# 8: NumLock +# 9: Alt +# 10: LevelThree +# 11: LAlt +# 12: RAlt +# 13: RControl +# 14: LControl +# 15: ScrollLock +# 16: LevelFive +# 17: AltGr +# 18: Meta +# 19: Super +# 20: Hyper + +# evdev 1 (0x1), QKeyCode "esc", number 0x1 +Escape 0x01 + +# evdev 2 (0x2), QKeyCode "1", number 0x2 +1 0x02 +exclam 0x02 shift +onesuperior 0x02 altgr +exclamdown 0x02 shift altgr + +# evdev 3 (0x3), QKeyCode "2", number 0x3 +2 0x03 +quotedbl 0x03 shift +at 0x03 altgr +oneeighth 0x03 shift altgr + +# evdev 4 (0x4), QKeyCode "3", number 0x4 +3 0x04 +numbersign 0x04 shift +sterling 0x04 altgr + +# evdev 5 (0x5), QKeyCode "4", number 0x5 +4 0x05 +dollar 0x05 shift +section 0x05 altgr + +# evdev 6 (0x6), QKeyCode "5", number 0x6 +5 0x06 +percent 0x06 shift +onehalf 0x06 altgr +threeeighths 0x06 shift altgr + +# evdev 7 (0x7), QKeyCode "6", number 0x7 +6 0x07 +ampersand 0x07 shift +notsign 0x07 altgr +fiveeighths 0x07 shift altgr + +# evdev 8 (0x8), QKeyCode "7", number 0x8 +7 0x08 +slash 0x08 shift +braceleft 0x08 altgr +seveneighths 0x08 shift altgr + +# evdev 9 (0x9), QKeyCode "8", number 0x9 +8 0x09 +parenleft 0x09 shift +bracketleft 0x09 altgr +trademark 0x09 shift altgr + +# evdev 10 (0xa), QKeyCode "9", number 0xa +9 0x0a +parenright 0x0a shift +bracketright 0x0a altgr +plusminus 0x0a shift altgr + +# evdev 11 (0xb), QKeyCode "0", number 0xb +0 0x0b +equal 0x0b shift +braceright 0x0b altgr +degree 0x0b shift altgr + +# evdev 12 (0xc), QKeyCode "minus", number 0xc +apostrophe 0x0c +question 0x0c shift +backslash 0x0c altgr +questiondown 0x0c shift altgr + +# evdev 13 (0xd), QKeyCode "equal", number 0xd +guillemotleft 0x0d +guillemotright 0x0d shift +dead_cedilla 0x0d altgr +dead_ogonek 0x0d shift altgr + +# evdev 14 (0xe), QKeyCode "backspace", number 0xe +BackSpace 0x0e + +# evdev 15 (0xf), QKeyCode "tab", number 0xf +Tab 0x0f +ISO_Left_Tab 0x0f shift + +# evdev 16 (0x10), QKeyCode "q", number 0x10 +q 0x10 +Q 0x10 shift +at 0x10 altgr +Greek_OMEGA 0x10 shift altgr + +# evdev 17 (0x11), QKeyCode "w", number 0x11 +w 0x11 +W 0x11 shift +lstroke 0x11 altgr +Lstroke 0x11 shift altgr + +# evdev 18 (0x12), QKeyCode "e", number 0x12 +e 0x12 +E 0x12 shift +EuroSign 0x12 altgr +cent 0x12 shift altgr + +# evdev 19 (0x13), QKeyCode "r", number 0x13 +r 0x13 +R 0x13 shift +paragraph 0x13 altgr +registered 0x13 shift altgr + +# evdev 20 (0x14), QKeyCode "t", number 0x14 +t 0x14 +T 0x14 shift +tslash 0x14 altgr +Tslash 0x14 shift altgr + +# evdev 21 (0x15), QKeyCode "y", number 0x15 +y 0x15 +Y 0x15 shift +leftarrow 0x15 altgr +yen 0x15 shift altgr + +# evdev 22 (0x16), QKeyCode "u", number 0x16 +u 0x16 +U 0x16 shift +downarrow 0x16 altgr +uparrow 0x16 shift altgr + +# evdev 23 (0x17), QKeyCode "i", number 0x17 +i 0x17 +I 0x17 shift +rightarrow 0x17 altgr +idotless 0x17 shift altgr + +# evdev 24 (0x18), QKeyCode "o", number 0x18 +o 0x18 +O 0x18 shift +oslash 0x18 altgr +Oslash 0x18 shift altgr + +# evdev 25 (0x19), QKeyCode "p", number 0x19 +p 0x19 +P 0x19 shift +thorn 0x19 altgr +THORN 0x19 shift altgr + +# evdev 26 (0x1a), QKeyCode "bracket_left", number 0x1a +plus 0x1a +asterisk 0x1a shift +dead_diaeresis 0x1a altgr +dead_abovering 0x1a shift altgr + +# evdev 27 (0x1b), QKeyCode "bracket_right", number 0x1b +dead_acute 0x1b +dead_grave 0x1b shift +dead_tilde 0x1b altgr +dead_macron 0x1b shift altgr + +# evdev 28 (0x1c), QKeyCode "ret", number 0x1c +Return 0x1c + +# evdev 29 (0x1d), QKeyCode "ctrl", number 0x1d +Control_L 0x1d + +# evdev 30 (0x1e), QKeyCode "a", number 0x1e +a 0x1e +A 0x1e shift +ae 0x1e altgr +AE 0x1e shift altgr + +# evdev 31 (0x1f), QKeyCode "s", number 0x1f +s 0x1f +S 0x1f shift +ssharp 0x1f altgr +section 0x1f shift altgr + +# evdev 32 (0x20), QKeyCode "d", number 0x20 +d 0x20 +D 0x20 shift +eth 0x20 altgr +ETH 0x20 shift altgr + +# evdev 33 (0x21), QKeyCode "f", number 0x21 +f 0x21 +F 0x21 shift +dstroke 0x21 altgr +ordfeminine 0x21 shift altgr + +# evdev 34 (0x22), QKeyCode "g", number 0x22 +g 0x22 +G 0x22 shift +eng 0x22 altgr +ENG 0x22 shift altgr + +# evdev 35 (0x23), QKeyCode "h", number 0x23 +h 0x23 +H 0x23 shift +hstroke 0x23 altgr +Hstroke 0x23 shift altgr + +# evdev 36 (0x24), QKeyCode "j", number 0x24 +j 0x24 +J 0x24 shift +dead_hook 0x24 altgr +dead_horn 0x24 shift altgr + +# evdev 37 (0x25), QKeyCode "k", number 0x25 +k 0x25 +K 0x25 shift +kra 0x25 altgr +ampersand 0x25 shift altgr + +# evdev 38 (0x26), QKeyCode "l", number 0x26 +l 0x26 +L 0x26 shift +lstroke 0x26 altgr +Lstroke 0x26 shift altgr + +# evdev 39 (0x27), QKeyCode "semicolon", number 0x27 +ccedilla 0x27 +Ccedilla 0x27 shift +dead_acute 0x27 altgr +dead_doubleacute 0x27 shift altgr + +# evdev 40 (0x28), QKeyCode "apostrophe", number 0x28 +masculine 0x28 +ordfeminine 0x28 shift +dead_circumflex 0x28 altgr +dead_caron 0x28 shift altgr + +# evdev 41 (0x29), QKeyCode "grave_accent", number 0x29 +backslash 0x29 +bar 0x29 shift +notsign 0x29 altgr + +# evdev 42 (0x2a), QKeyCode "shift", number 0x2a +Shift_L 0x2a + +# evdev 43 (0x2b), QKeyCode "backslash", number 0x2b +dead_tilde 0x2b +dead_circumflex 0x2b shift +dead_grave 0x2b altgr +dead_breve 0x2b shift altgr + +# evdev 44 (0x2c), QKeyCode "z", number 0x2c +z 0x2c +Z 0x2c shift +guillemotleft 0x2c altgr +less 0x2c shift altgr + +# evdev 45 (0x2d), QKeyCode "x", number 0x2d +x 0x2d +X 0x2d shift +guillemotright 0x2d altgr +greater 0x2d shift altgr + +# evdev 46 (0x2e), QKeyCode "c", number 0x2e +c 0x2e +C 0x2e shift +cent 0x2e altgr +copyright 0x2e shift altgr + +# evdev 47 (0x2f), QKeyCode "v", number 0x2f +v 0x2f +V 0x2f shift +leftdoublequotemark 0x2f altgr +leftsinglequotemark 0x2f shift altgr + +# evdev 48 (0x30), QKeyCode "b", number 0x30 +b 0x30 +B 0x30 shift +rightdoublequotemark 0x30 altgr +rightsinglequotemark 0x30 shift altgr + +# evdev 49 (0x31), QKeyCode "n", number 0x31 +n 0x31 +N 0x31 shift + +# evdev 50 (0x32), QKeyCode "m", number 0x32 +m 0x32 +M 0x32 shift +mu 0x32 altgr +masculine 0x32 shift altgr + +# evdev 51 (0x33), QKeyCode "comma", number 0x33 +comma 0x33 +semicolon 0x33 shift +horizconnector 0x33 altgr +multiply 0x33 shift altgr + +# evdev 52 (0x34), QKeyCode "dot", number 0x34 +period 0x34 +colon 0x34 shift +periodcentered 0x34 altgr +division 0x34 shift altgr + +# evdev 53 (0x35), QKeyCode "slash", number 0x35 +minus 0x35 +underscore 0x35 shift +dead_belowdot 0x35 altgr +dead_abovedot 0x35 shift altgr + +# evdev 54 (0x36), QKeyCode "shift_r", number 0x36 +Shift_R 0x36 + +# evdev 55 (0x37), QKeyCode "kp_multiply", number 0x37 +KP_Multiply 0x37 + +# evdev 56 (0x38), QKeyCode "alt", number 0x38 +Alt_L 0x38 +Meta_L 0x38 shift + +# evdev 57 (0x39), QKeyCode "spc", number 0x39 +space 0x39 + +# evdev 58 (0x3a), QKeyCode "caps_lock", number 0x3a +Caps_Lock 0x3a + +# evdev 59 (0x3b), QKeyCode "f1", number 0x3b +F1 0x3b + +# evdev 60 (0x3c), QKeyCode "f2", number 0x3c +F2 0x3c + +# evdev 61 (0x3d), QKeyCode "f3", number 0x3d +F3 0x3d + +# evdev 62 (0x3e), QKeyCode "f4", number 0x3e +F4 0x3e + +# evdev 63 (0x3f), QKeyCode "f5", number 0x3f +F5 0x3f + +# evdev 64 (0x40), QKeyCode "f6", number 0x40 +F6 0x40 + +# evdev 65 (0x41), QKeyCode "f7", number 0x41 +F7 0x41 + +# evdev 66 (0x42), QKeyCode "f8", number 0x42 +F8 0x42 + +# evdev 67 (0x43), QKeyCode "f9", number 0x43 +F9 0x43 + +# evdev 68 (0x44), QKeyCode "f10", number 0x44 +F10 0x44 + +# evdev 69 (0x45), QKeyCode "num_lock", number 0x45 +Num_Lock 0x45 + +# evdev 70 (0x46), QKeyCode "scroll_lock", number 0x46 +Scroll_Lock 0x46 + +# evdev 71 (0x47), QKeyCode "kp_7", number 0x47 +KP_Home 0x47 +KP_7 0x47 numlock + +# evdev 72 (0x48), QKeyCode "kp_8", number 0x48 +KP_Up 0x48 +KP_8 0x48 numlock + +# evdev 73 (0x49), QKeyCode "kp_9", number 0x49 +KP_Prior 0x49 +KP_9 0x49 numlock + +# evdev 74 (0x4a), QKeyCode "kp_subtract", number 0x4a +KP_Subtract 0x4a + +# evdev 75 (0x4b), QKeyCode "kp_4", number 0x4b +KP_Left 0x4b +KP_4 0x4b numlock + +# evdev 76 (0x4c), QKeyCode "kp_5", number 0x4c +KP_Begin 0x4c +KP_5 0x4c numlock + +# evdev 77 (0x4d), QKeyCode "kp_6", number 0x4d +KP_Right 0x4d +KP_6 0x4d numlock + +# evdev 78 (0x4e), QKeyCode "kp_add", number 0x4e +KP_Add 0x4e + +# evdev 79 (0x4f), QKeyCode "kp_1", number 0x4f +KP_End 0x4f +KP_1 0x4f numlock + +# evdev 80 (0x50), QKeyCode "kp_2", number 0x50 +KP_Down 0x50 +KP_2 0x50 numlock + +# evdev 81 (0x51), QKeyCode "kp_3", number 0x51 +KP_Next 0x51 +KP_3 0x51 numlock + +# evdev 82 (0x52), QKeyCode "kp_0", number 0x52 +KP_Insert 0x52 +KP_0 0x52 numlock + +# evdev 83 (0x53), QKeyCode "kp_decimal", number 0x53 +KP_Delete 0x53 +KP_Decimal 0x53 numlock + +# evdev 84 (0x54): no evdev -> QKeyCode mapping (xkb keysym ISO_Level3_Shift) + +# evdev 85 (0x55): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 86 (0x56), QKeyCode "less", number 0x56 +less 0x56 +greater 0x56 shift +backslash 0x56 altgr + +# evdev 87 (0x57), QKeyCode "f11", number 0x57 +F11 0x57 + +# evdev 88 (0x58), QKeyCode "f12", number 0x58 +F12 0x58 + +# evdev 89 (0x59), QKeyCode "ro", number 0x73 + +# evdev 90 (0x5a): no evdev -> QKeyCode mapping (xkb keysym Katakana) + +# evdev 91 (0x5b), QKeyCode "hiragana", number 0x77 +Hiragana 0x77 + +# evdev 92 (0x5c), QKeyCode "henkan", number 0x79 +Henkan_Mode 0x79 + +# evdev 93 (0x5d), QKeyCode "katakanahiragana", number 0x70 +Hiragana_Katakana 0x70 + +# evdev 94 (0x5e), QKeyCode "muhenkan", number 0x7b +Muhenkan 0x7b + +# evdev 95 (0x5f): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 96 (0x60), QKeyCode "kp_enter", number 0x9c +KP_Enter 0x9c + +# evdev 97 (0x61), QKeyCode "ctrl_r", number 0x9d +Control_R 0x9d + +# evdev 98 (0x62), QKeyCode "kp_divide", number 0xb5 +KP_Divide 0xb5 + +# evdev 99 (0x63), QKeyCode "sysrq", number 0x54 +Print 0x54 + +# evdev 100 (0x64), QKeyCode "alt_r", number 0xb8 +ISO_Level3_Shift 0xb8 + +# evdev 101 (0x65), QKeyCode "lf", number 0x5b +Linefeed 0x5b + +# evdev 102 (0x66), QKeyCode "home", number 0xc7 +Home 0xc7 + +# evdev 103 (0x67), QKeyCode "up", number 0xc8 +Up 0xc8 + +# evdev 104 (0x68), QKeyCode "pgup", number 0xc9 +Prior 0xc9 + +# evdev 105 (0x69), QKeyCode "left", number 0xcb +Left 0xcb + +# evdev 106 (0x6a), QKeyCode "right", number 0xcd +Right 0xcd + +# evdev 107 (0x6b), QKeyCode "end", number 0xcf +End 0xcf + +# evdev 108 (0x6c), QKeyCode "down", number 0xd0 +Down 0xd0 + +# evdev 109 (0x6d), QKeyCode "pgdn", number 0xd1 +Next 0xd1 + +# evdev 110 (0x6e), QKeyCode "insert", number 0xd2 +Insert 0xd2 + +# evdev 111 (0x6f), QKeyCode "delete", number 0xd3 +Delete 0xd3 + +# evdev 112 (0x70): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 113 (0x71), QKeyCode "audiomute", number 0xa0 +XF86AudioMute 0xa0 + +# evdev 114 (0x72), QKeyCode "volumedown", number 0xae +XF86AudioLowerVolume 0xae + +# evdev 115 (0x73), QKeyCode "volumeup", number 0xb0 +XF86AudioRaiseVolume 0xb0 + +# evdev 116 (0x74), QKeyCode "power", number 0xde +XF86PowerOff 0xde + +# evdev 117 (0x75), QKeyCode "kp_equals", number 0x59 +KP_Equal 0x59 + +# evdev 118 (0x76): no evdev -> QKeyCode mapping (xkb keysym plusminus) + +# evdev 119 (0x77), QKeyCode "pause", number 0xc6 +Pause 0xc6 + +# evdev 120 (0x78): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchA) + +# evdev 121 (0x79), QKeyCode "kp_comma", number 0x7e +KP_Decimal 0x7e + +# evdev 122 (0x7a): no evdev -> QKeyCode mapping (xkb keysym Hangul) + +# evdev 123 (0x7b): no evdev -> QKeyCode mapping (xkb keysym Hangul_Hanja) + +# evdev 124 (0x7c), QKeyCode "yen", number 0x7d + +# evdev 125 (0x7d), QKeyCode "meta_l", number 0xdb +Super_L 0xdb + +# evdev 126 (0x7e), QKeyCode "meta_r", number 0xdc +Super_R 0xdc + +# evdev 127 (0x7f), QKeyCode "compose", number 0xdd +Menu 0xdd + +# evdev 128 (0x80), QKeyCode "stop", number 0xe8 +Cancel 0xe8 + +# evdev 129 (0x81), QKeyCode "again", number 0x85 +Redo 0x85 + +# evdev 130 (0x82), QKeyCode "props", number 0x86 +SunProps 0x86 + +# evdev 131 (0x83), QKeyCode "undo", number 0x87 +Undo 0x87 + +# evdev 132 (0x84), QKeyCode "front", number 0x8c +SunFront 0x8c + +# evdev 133 (0x85), QKeyCode "copy", number 0xf8 +XF86Copy 0xf8 + +# evdev 134 (0x86), QKeyCode "open", number 0x64 +XF86Open 0x64 + +# evdev 135 (0x87), QKeyCode "paste", number 0x65 +XF86Paste 0x65 + +# evdev 136 (0x88), QKeyCode "find", number 0xc1 +Find 0xc1 + +# evdev 137 (0x89), QKeyCode "cut", number 0xbc +XF86Cut 0xbc + +# evdev 138 (0x8a), QKeyCode "help", number 0xf5 +Help 0xf5 + +# evdev 139 (0x8b), QKeyCode "menu", number 0x9e +XF86MenuKB 0x9e + +# evdev 140 (0x8c), QKeyCode "calculator", number 0xa1 +XF86Calculator 0xa1 + +# evdev 141 (0x8d): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 142 (0x8e), QKeyCode "sleep", number 0xdf +XF86Sleep 0xdf + +# evdev 143 (0x8f), QKeyCode "wake", number 0xe3 +XF86WakeUp 0xe3 + +# evdev 144 (0x90): no evdev -> QKeyCode mapping (xkb keysym XF86Explorer) + +# evdev 145 (0x91): no evdev -> QKeyCode mapping (xkb keysym XF86Send) + +# evdev 146 (0x92): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 147 (0x93): no evdev -> QKeyCode mapping (xkb keysym XF86Xfer) + +# evdev 148 (0x94): no evdev -> QKeyCode mapping (xkb keysym XF86Launch1) + +# evdev 149 (0x95): no evdev -> QKeyCode mapping (xkb keysym XF86Launch2) + +# evdev 150 (0x96): no evdev -> QKeyCode mapping (xkb keysym XF86WWW) + +# evdev 151 (0x97): no evdev -> QKeyCode mapping (xkb keysym XF86DOS) + +# evdev 152 (0x98): no evdev -> QKeyCode mapping (xkb keysym XF86ScreenSaver) + +# evdev 153 (0x99): no evdev -> QKeyCode mapping (xkb keysym XF86RotateWindows) + +# evdev 154 (0x9a): no evdev -> QKeyCode mapping (xkb keysym XF86TaskPane) + +# evdev 155 (0x9b), QKeyCode "mail", number 0xec +XF86Mail 0xec + +# evdev 156 (0x9c), QKeyCode "ac_bookmarks", number 0xe6 +XF86Favorites 0xe6 + +# evdev 157 (0x9d), QKeyCode "computer", number 0xeb +XF86MyComputer 0xeb + +# evdev 158 (0x9e), QKeyCode "ac_back", number 0xea +XF86Back 0xea + +# evdev 159 (0x9f), QKeyCode "ac_forward", number 0xe9 +XF86Forward 0xe9 + +# evdev 160 (0xa0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 161 (0xa1): no evdev -> QKeyCode mapping (xkb keysym XF86Eject) + +# evdev 162 (0xa2): no evdev -> QKeyCode mapping (xkb keysym XF86Eject) + +# evdev 163 (0xa3), QKeyCode "audionext", number 0x99 +XF86AudioNext 0x99 + +# evdev 164 (0xa4), QKeyCode "audioplay", number 0xa2 +XF86AudioPlay 0xa2 +XF86AudioPause 0xa2 shift + +# evdev 165 (0xa5), QKeyCode "audioprev", number 0x90 +XF86AudioPrev 0x90 + +# evdev 166 (0xa6), QKeyCode "audiostop", number 0xa4 +XF86AudioStop 0xa4 +XF86Eject 0xa4 shift + +# evdev 167 (0xa7): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRecord) + +# evdev 168 (0xa8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRewind) + +# evdev 169 (0xa9): no evdev -> QKeyCode mapping (xkb keysym XF86Phone) + +# evdev 170 (0xaa): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 171 (0xab): no evdev -> QKeyCode mapping (xkb keysym XF86Tools) + +# evdev 172 (0xac), QKeyCode "ac_home", number 0xb2 +XF86HomePage 0xb2 + +# evdev 173 (0xad), QKeyCode "ac_refresh", number 0xe7 +XF86Reload 0xe7 + +# evdev 174 (0xae): no evdev -> QKeyCode mapping (xkb keysym XF86Close) + +# evdev 175 (0xaf): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 176 (0xb0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 177 (0xb1): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollUp) + +# evdev 178 (0xb2): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollDown) + +# evdev 179 (0xb3): no evdev -> QKeyCode mapping (xkb keysym parenleft) + +# evdev 180 (0xb4): no evdev -> QKeyCode mapping (xkb keysym parenright) + +# evdev 181 (0xb5): no evdev -> QKeyCode mapping (xkb keysym XF86New) + +# evdev 182 (0xb6): no evdev -> QKeyCode mapping (xkb keysym Redo) + +# evdev 183 (0xb7): no evdev -> QKeyCode mapping (xkb keysym XF86Tools) + +# evdev 184 (0xb8): no evdev -> QKeyCode mapping (xkb keysym XF86Launch5) + +# evdev 185 (0xb9): no evdev -> QKeyCode mapping (xkb keysym XF86Launch6) + +# evdev 186 (0xba): no evdev -> QKeyCode mapping (xkb keysym XF86Launch7) + +# evdev 187 (0xbb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch8) + +# evdev 188 (0xbc): no evdev -> QKeyCode mapping (xkb keysym XF86Launch9) + +# evdev 189 (0xbd): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 190 (0xbe): no evdev -> QKeyCode mapping (xkb keysym XF86AudioMicMute) + +# evdev 191 (0xbf): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadToggle) + +# evdev 192 (0xc0): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOn) + +# evdev 193 (0xc1): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOff) + +# evdev 194 (0xc2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 195 (0xc3): no evdev -> QKeyCode mapping (xkb keysym Mode_switch) + +# evdev 196 (0xc4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 197 (0xc5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 198 (0xc6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 199 (0xc7): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 200 (0xc8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay) + +# evdev 201 (0xc9): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPause) + +# evdev 202 (0xca): no evdev -> QKeyCode mapping (xkb keysym XF86Launch3) + +# evdev 203 (0xcb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch4) + +# evdev 204 (0xcc): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchB) + +# evdev 205 (0xcd): no evdev -> QKeyCode mapping (xkb keysym XF86Suspend) + +# evdev 206 (0xce): no evdev -> QKeyCode mapping (xkb keysym XF86Close) + +# evdev 207 (0xcf): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay) + +# evdev 208 (0xd0): no evdev -> QKeyCode mapping (xkb keysym XF86AudioForward) + +# evdev 209 (0xd1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 210 (0xd2): no evdev -> QKeyCode mapping (xkb keysym Print) + +# evdev 211 (0xd3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 212 (0xd4): no evdev -> QKeyCode mapping (xkb keysym XF86WebCam) + +# evdev 213 (0xd5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 214 (0xd6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 215 (0xd7): no evdev -> QKeyCode mapping (xkb keysym XF86Mail) + +# evdev 216 (0xd8): no evdev -> QKeyCode mapping (xkb keysym XF86Messenger) + +# evdev 217 (0xd9): no evdev -> QKeyCode mapping (xkb keysym XF86Search) + +# evdev 218 (0xda): no evdev -> QKeyCode mapping (xkb keysym XF86Go) + +# evdev 219 (0xdb): no evdev -> QKeyCode mapping (xkb keysym XF86Finance) + +# evdev 220 (0xdc): no evdev -> QKeyCode mapping (xkb keysym XF86Game) + +# evdev 221 (0xdd): no evdev -> QKeyCode mapping (xkb keysym XF86Shop) + +# evdev 222 (0xde): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 223 (0xdf): no evdev -> QKeyCode mapping (xkb keysym Cancel) + +# evdev 224 (0xe0): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessDown) + +# evdev 225 (0xe1): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessUp) + +# evdev 226 (0xe2), QKeyCode "mediaselect", number 0xed +XF86AudioMedia 0xed + +# evdev 227 (0xe3): no evdev -> QKeyCode mapping (xkb keysym XF86Display) + +# evdev 228 (0xe4): no evdev -> QKeyCode mapping (xkb keysym XF86KbdLightOnOff) + +# evdev 229 (0xe5): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessDown) + +# evdev 230 (0xe6): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessUp) + +# evdev 231 (0xe7): no evdev -> QKeyCode mapping (xkb keysym XF86Send) + +# evdev 232 (0xe8): no evdev -> QKeyCode mapping (xkb keysym XF86Reply) + +# evdev 233 (0xe9): no evdev -> QKeyCode mapping (xkb keysym XF86MailForward) + +# evdev 234 (0xea): no evdev -> QKeyCode mapping (xkb keysym XF86Save) + +# evdev 235 (0xeb): no evdev -> QKeyCode mapping (xkb keysym XF86Documents) + +# evdev 236 (0xec): no evdev -> QKeyCode mapping (xkb keysym XF86Battery) + +# evdev 237 (0xed): no evdev -> QKeyCode mapping (xkb keysym XF86Bluetooth) + +# evdev 238 (0xee): no evdev -> QKeyCode mapping (xkb keysym XF86WLAN) + +# evdev 239 (0xef): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 240 (0xf0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 241 (0xf1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 242 (0xf2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 243 (0xf3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 244 (0xf4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 245 (0xf5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 246 (0xf6): no evdev -> QKeyCode mapping (xkb keysym Invalid) + +# evdev 247 (0xf7): no evdev -> QKeyCode mapping (xkb keysym Invalid) + +# +# quirks section start +# +# Sometimes multiple keysyms map to the same keycodes. +# The keycode -> keysym lookup finds only one of the +# keysyms. So append them here. +# + +Print 0x54 +Sys_Req 0x54 +Execute 0x54 +KP_Decimal 0x53 numlock +KP_Separator 0x53 numlock +Alt_R 0xb8 +ISO_Level3_Shift 0xb8 +Mode_switch 0xb8 + +# quirks section end diff --git a/app/src/main/assets/roms/keymaps/pt-br b/app/src/main/assets/roms/keymaps/pt-br new file mode 100644 index 0000000..2d409c0 --- /dev/null +++ b/app/src/main/assets/roms/keymaps/pt-br @@ -0,0 +1,840 @@ +# +# generated by qemu-keymap +# model : pc105 +# layout : br +# variant : - +# options : - + +# name: "Portuguese (Brazil)" + +# modifiers +# 0: Shift +# 1: Lock +# 2: Control +# 3: Mod1 +# 4: Mod2 +# 5: Mod3 +# 6: Mod4 +# 7: Mod5 +# 8: NumLock +# 9: Alt +# 10: LevelThree +# 11: LAlt +# 12: RAlt +# 13: RControl +# 14: LControl +# 15: ScrollLock +# 16: LevelFive +# 17: AltGr +# 18: Meta +# 19: Super +# 20: Hyper + +# evdev 1 (0x1), QKeyCode "esc", number 0x1 +Escape 0x01 + +# evdev 2 (0x2), QKeyCode "1", number 0x2 +1 0x02 +exclam 0x02 shift +onesuperior 0x02 altgr +exclamdown 0x02 shift altgr + +# evdev 3 (0x3), QKeyCode "2", number 0x3 +2 0x03 +at 0x03 shift +twosuperior 0x03 altgr +onehalf 0x03 shift altgr + +# evdev 4 (0x4), QKeyCode "3", number 0x4 +3 0x04 +numbersign 0x04 shift +threesuperior 0x04 altgr +threequarters 0x04 shift altgr + +# evdev 5 (0x5), QKeyCode "4", number 0x5 +4 0x05 +dollar 0x05 shift +sterling 0x05 altgr +onequarter 0x05 shift altgr + +# evdev 6 (0x6), QKeyCode "5", number 0x6 +5 0x06 +percent 0x06 shift +cent 0x06 altgr +threeeighths 0x06 shift altgr + +# evdev 7 (0x7), QKeyCode "6", number 0x7 +6 0x07 +dead_diaeresis 0x07 shift +notsign 0x07 altgr +diaeresis 0x07 shift altgr + +# evdev 8 (0x8), QKeyCode "7", number 0x8 +7 0x08 +ampersand 0x08 shift +braceleft 0x08 altgr +seveneighths 0x08 shift altgr + +# evdev 9 (0x9), QKeyCode "8", number 0x9 +8 0x09 +asterisk 0x09 shift +bracketleft 0x09 altgr +trademark 0x09 shift altgr + +# evdev 10 (0xa), QKeyCode "9", number 0xa +9 0x0a +parenleft 0x0a shift +bracketright 0x0a altgr +plusminus 0x0a shift altgr + +# evdev 11 (0xb), QKeyCode "0", number 0xb +0 0x0b +parenright 0x0b shift +braceright 0x0b altgr +degree 0x0b shift altgr + +# evdev 12 (0xc), QKeyCode "minus", number 0xc +minus 0x0c +underscore 0x0c shift +backslash 0x0c altgr +questiondown 0x0c shift altgr + +# evdev 13 (0xd), QKeyCode "equal", number 0xd +equal 0x0d +plus 0x0d shift +section 0x0d altgr +dead_ogonek 0x0d shift altgr + +# evdev 14 (0xe), QKeyCode "backspace", number 0xe +BackSpace 0x0e + +# evdev 15 (0xf), QKeyCode "tab", number 0xf +Tab 0x0f +ISO_Left_Tab 0x0f shift + +# evdev 16 (0x10), QKeyCode "q", number 0x10 +q 0x10 +Q 0x10 shift +slash 0x10 altgr + +# evdev 17 (0x11), QKeyCode "w", number 0x11 +w 0x11 +W 0x11 shift +question 0x11 altgr + +# evdev 18 (0x12), QKeyCode "e", number 0x12 +e 0x12 +E 0x12 shift +EuroSign 0x12 altgr + +# evdev 19 (0x13), QKeyCode "r", number 0x13 +r 0x13 +R 0x13 shift +registered 0x13 altgr + +# evdev 20 (0x14), QKeyCode "t", number 0x14 +t 0x14 +T 0x14 shift +tslash 0x14 altgr +Tslash 0x14 shift altgr + +# evdev 21 (0x15), QKeyCode "y", number 0x15 +y 0x15 +Y 0x15 shift +leftarrow 0x15 altgr +yen 0x15 shift altgr + +# evdev 22 (0x16), QKeyCode "u", number 0x16 +u 0x16 +U 0x16 shift +downarrow 0x16 altgr +uparrow 0x16 shift altgr + +# evdev 23 (0x17), QKeyCode "i", number 0x17 +i 0x17 +I 0x17 shift +rightarrow 0x17 altgr +idotless 0x17 shift altgr + +# evdev 24 (0x18), QKeyCode "o", number 0x18 +o 0x18 +O 0x18 shift +oslash 0x18 altgr +Oslash 0x18 shift altgr + +# evdev 25 (0x19), QKeyCode "p", number 0x19 +p 0x19 +P 0x19 shift +thorn 0x19 altgr +THORN 0x19 shift altgr + +# evdev 26 (0x1a), QKeyCode "bracket_left", number 0x1a +dead_acute 0x1a +dead_grave 0x1a shift +acute 0x1a altgr +grave 0x1a shift altgr + +# evdev 27 (0x1b), QKeyCode "bracket_right", number 0x1b +bracketleft 0x1b +braceleft 0x1b shift +ordfeminine 0x1b altgr +dead_macron 0x1b shift altgr + +# evdev 28 (0x1c), QKeyCode "ret", number 0x1c +Return 0x1c + +# evdev 29 (0x1d), QKeyCode "ctrl", number 0x1d +Control_L 0x1d + +# evdev 30 (0x1e), QKeyCode "a", number 0x1e +a 0x1e +A 0x1e shift +ae 0x1e altgr +AE 0x1e shift altgr + +# evdev 31 (0x1f), QKeyCode "s", number 0x1f +s 0x1f +S 0x1f shift +ssharp 0x1f altgr +section 0x1f shift altgr + +# evdev 32 (0x20), QKeyCode "d", number 0x20 +d 0x20 +D 0x20 shift +eth 0x20 altgr +ETH 0x20 shift altgr + +# evdev 33 (0x21), QKeyCode "f", number 0x21 +f 0x21 +F 0x21 shift +dstroke 0x21 altgr +ordfeminine 0x21 shift altgr + +# evdev 34 (0x22), QKeyCode "g", number 0x22 +g 0x22 +G 0x22 shift +eng 0x22 altgr +ENG 0x22 shift altgr + +# evdev 35 (0x23), QKeyCode "h", number 0x23 +h 0x23 +H 0x23 shift +hstroke 0x23 altgr +Hstroke 0x23 shift altgr + +# evdev 36 (0x24), QKeyCode "j", number 0x24 +j 0x24 +J 0x24 shift +dead_hook 0x24 altgr +dead_horn 0x24 shift altgr + +# evdev 37 (0x25), QKeyCode "k", number 0x25 +k 0x25 +K 0x25 shift +kra 0x25 altgr +ampersand 0x25 shift altgr + +# evdev 38 (0x26), QKeyCode "l", number 0x26 +l 0x26 +L 0x26 shift +lstroke 0x26 altgr +Lstroke 0x26 shift altgr + +# evdev 39 (0x27), QKeyCode "semicolon", number 0x27 +ccedilla 0x27 +Ccedilla 0x27 shift +dead_acute 0x27 altgr +dead_doubleacute 0x27 shift altgr + +# evdev 40 (0x28), QKeyCode "apostrophe", number 0x28 +dead_tilde 0x28 +dead_circumflex 0x28 shift +asciitilde 0x28 altgr +asciicircum 0x28 shift altgr + +# evdev 41 (0x29), QKeyCode "grave_accent", number 0x29 +apostrophe 0x29 +quotedbl 0x29 shift +notsign 0x29 altgr + +# evdev 42 (0x2a), QKeyCode "shift", number 0x2a +Shift_L 0x2a + +# evdev 43 (0x2b), QKeyCode "backslash", number 0x2b +bracketright 0x2b +braceright 0x2b shift +masculine 0x2b altgr + +# evdev 44 (0x2c), QKeyCode "z", number 0x2c +z 0x2c +Z 0x2c shift +guillemotleft 0x2c altgr +less 0x2c shift altgr + +# evdev 45 (0x2d), QKeyCode "x", number 0x2d +x 0x2d +X 0x2d shift +guillemotright 0x2d altgr +greater 0x2d shift altgr + +# evdev 46 (0x2e), QKeyCode "c", number 0x2e +c 0x2e +C 0x2e shift +copyright 0x2e altgr + +# evdev 47 (0x2f), QKeyCode "v", number 0x2f +v 0x2f +V 0x2f shift +leftdoublequotemark 0x2f altgr +leftsinglequotemark 0x2f shift altgr + +# evdev 48 (0x30), QKeyCode "b", number 0x30 +b 0x30 +B 0x30 shift +rightdoublequotemark 0x30 altgr +rightsinglequotemark 0x30 shift altgr + +# evdev 49 (0x31), QKeyCode "n", number 0x31 +n 0x31 +N 0x31 shift + +# evdev 50 (0x32), QKeyCode "m", number 0x32 +m 0x32 +M 0x32 shift +mu 0x32 altgr + +# evdev 51 (0x33), QKeyCode "comma", number 0x33 +comma 0x33 +less 0x33 shift +horizconnector 0x33 altgr +multiply 0x33 shift altgr + +# evdev 52 (0x34), QKeyCode "dot", number 0x34 +period 0x34 +greater 0x34 shift +periodcentered 0x34 altgr +division 0x34 shift altgr + +# evdev 53 (0x35), QKeyCode "slash", number 0x35 +semicolon 0x35 +colon 0x35 shift +dead_belowdot 0x35 altgr +dead_abovedot 0x35 shift altgr + +# evdev 54 (0x36), QKeyCode "shift_r", number 0x36 +Shift_R 0x36 + +# evdev 55 (0x37), QKeyCode "kp_multiply", number 0x37 +KP_Multiply 0x37 + +# evdev 56 (0x38), QKeyCode "alt", number 0x38 +Alt_L 0x38 +Meta_L 0x38 shift + +# evdev 57 (0x39), QKeyCode "spc", number 0x39 +space 0x39 + +# evdev 58 (0x3a), QKeyCode "caps_lock", number 0x3a +Caps_Lock 0x3a + +# evdev 59 (0x3b), QKeyCode "f1", number 0x3b +F1 0x3b + +# evdev 60 (0x3c), QKeyCode "f2", number 0x3c +F2 0x3c + +# evdev 61 (0x3d), QKeyCode "f3", number 0x3d +F3 0x3d + +# evdev 62 (0x3e), QKeyCode "f4", number 0x3e +F4 0x3e + +# evdev 63 (0x3f), QKeyCode "f5", number 0x3f +F5 0x3f + +# evdev 64 (0x40), QKeyCode "f6", number 0x40 +F6 0x40 + +# evdev 65 (0x41), QKeyCode "f7", number 0x41 +F7 0x41 + +# evdev 66 (0x42), QKeyCode "f8", number 0x42 +F8 0x42 + +# evdev 67 (0x43), QKeyCode "f9", number 0x43 +F9 0x43 + +# evdev 68 (0x44), QKeyCode "f10", number 0x44 +F10 0x44 + +# evdev 69 (0x45), QKeyCode "num_lock", number 0x45 +Num_Lock 0x45 + +# evdev 70 (0x46), QKeyCode "scroll_lock", number 0x46 +Scroll_Lock 0x46 + +# evdev 71 (0x47), QKeyCode "kp_7", number 0x47 +KP_Home 0x47 +KP_7 0x47 numlock + +# evdev 72 (0x48), QKeyCode "kp_8", number 0x48 +KP_Up 0x48 +KP_8 0x48 numlock + +# evdev 73 (0x49), QKeyCode "kp_9", number 0x49 +KP_Prior 0x49 +KP_9 0x49 numlock + +# evdev 74 (0x4a), QKeyCode "kp_subtract", number 0x4a +KP_Subtract 0x4a + +# evdev 75 (0x4b), QKeyCode "kp_4", number 0x4b +KP_Left 0x4b +KP_4 0x4b numlock + +# evdev 76 (0x4c), QKeyCode "kp_5", number 0x4c +KP_Begin 0x4c +KP_5 0x4c numlock + +# evdev 77 (0x4d), QKeyCode "kp_6", number 0x4d +KP_Right 0x4d +KP_6 0x4d numlock + +# evdev 78 (0x4e), QKeyCode "kp_add", number 0x4e +KP_Add 0x4e + +# evdev 79 (0x4f), QKeyCode "kp_1", number 0x4f +KP_End 0x4f +KP_1 0x4f numlock + +# evdev 80 (0x50), QKeyCode "kp_2", number 0x50 +KP_Down 0x50 +KP_2 0x50 numlock + +# evdev 81 (0x51), QKeyCode "kp_3", number 0x51 +KP_Next 0x51 +KP_3 0x51 numlock + +# evdev 82 (0x52), QKeyCode "kp_0", number 0x52 +KP_Insert 0x52 +KP_0 0x52 numlock + +# evdev 83 (0x53), QKeyCode "kp_decimal", number 0x53 +KP_Delete 0x53 +KP_Separator 0x53 numlock + +# evdev 84 (0x54): no evdev -> QKeyCode mapping (xkb keysym ISO_Level3_Shift) + +# evdev 85 (0x55): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 86 (0x56), QKeyCode "less", number 0x56 +backslash 0x56 +bar 0x56 shift +masculine 0x56 altgr +dead_breve 0x56 shift altgr + +# evdev 87 (0x57), QKeyCode "f11", number 0x57 +F11 0x57 + +# evdev 88 (0x58), QKeyCode "f12", number 0x58 +F12 0x58 + +# evdev 89 (0x59), QKeyCode "ro", number 0x73 +slash 0x73 +question 0x73 shift +degree 0x73 altgr +questiondown 0x73 shift altgr + +# evdev 90 (0x5a): no evdev -> QKeyCode mapping (xkb keysym Katakana) + +# evdev 91 (0x5b), QKeyCode "hiragana", number 0x77 +Hiragana 0x77 + +# evdev 92 (0x5c), QKeyCode "henkan", number 0x79 +Henkan_Mode 0x79 + +# evdev 93 (0x5d), QKeyCode "katakanahiragana", number 0x70 +Hiragana_Katakana 0x70 + +# evdev 94 (0x5e), QKeyCode "muhenkan", number 0x7b +Muhenkan 0x7b + +# evdev 95 (0x5f): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 96 (0x60), QKeyCode "kp_enter", number 0x9c +KP_Enter 0x9c + +# evdev 97 (0x61), QKeyCode "ctrl_r", number 0x9d +Control_R 0x9d + +# evdev 98 (0x62), QKeyCode "kp_divide", number 0xb5 +KP_Divide 0xb5 + +# evdev 99 (0x63), QKeyCode "sysrq", number 0x54 +Print 0x54 + +# evdev 100 (0x64), QKeyCode "alt_r", number 0xb8 +ISO_Level3_Shift 0xb8 + +# evdev 101 (0x65), QKeyCode "lf", number 0x5b +Linefeed 0x5b + +# evdev 102 (0x66), QKeyCode "home", number 0xc7 +Home 0xc7 + +# evdev 103 (0x67), QKeyCode "up", number 0xc8 +Up 0xc8 + +# evdev 104 (0x68), QKeyCode "pgup", number 0xc9 +Prior 0xc9 + +# evdev 105 (0x69), QKeyCode "left", number 0xcb +Left 0xcb + +# evdev 106 (0x6a), QKeyCode "right", number 0xcd +Right 0xcd + +# evdev 107 (0x6b), QKeyCode "end", number 0xcf +End 0xcf + +# evdev 108 (0x6c), QKeyCode "down", number 0xd0 +Down 0xd0 + +# evdev 109 (0x6d), QKeyCode "pgdn", number 0xd1 +Next 0xd1 + +# evdev 110 (0x6e), QKeyCode "insert", number 0xd2 +Insert 0xd2 + +# evdev 111 (0x6f), QKeyCode "delete", number 0xd3 +Delete 0xd3 + +# evdev 112 (0x70): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 113 (0x71), QKeyCode "audiomute", number 0xa0 +XF86AudioMute 0xa0 + +# evdev 114 (0x72), QKeyCode "volumedown", number 0xae +XF86AudioLowerVolume 0xae + +# evdev 115 (0x73), QKeyCode "volumeup", number 0xb0 +XF86AudioRaiseVolume 0xb0 + +# evdev 116 (0x74), QKeyCode "power", number 0xde +XF86PowerOff 0xde + +# evdev 117 (0x75), QKeyCode "kp_equals", number 0x59 +KP_Equal 0x59 + +# evdev 118 (0x76): no evdev -> QKeyCode mapping (xkb keysym plusminus) + +# evdev 119 (0x77), QKeyCode "pause", number 0xc6 +Pause 0xc6 + +# evdev 120 (0x78): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchA) + +# evdev 121 (0x79), QKeyCode "kp_comma", number 0x7e +KP_Decimal 0x7e + +# evdev 122 (0x7a): no evdev -> QKeyCode mapping (xkb keysym Hangul) + +# evdev 123 (0x7b): no evdev -> QKeyCode mapping (xkb keysym Hangul_Hanja) + +# evdev 124 (0x7c), QKeyCode "yen", number 0x7d + +# evdev 125 (0x7d), QKeyCode "meta_l", number 0xdb +Super_L 0xdb + +# evdev 126 (0x7e), QKeyCode "meta_r", number 0xdc +Super_R 0xdc + +# evdev 127 (0x7f), QKeyCode "compose", number 0xdd +Menu 0xdd + +# evdev 128 (0x80), QKeyCode "stop", number 0xe8 +Cancel 0xe8 + +# evdev 129 (0x81), QKeyCode "again", number 0x85 +Redo 0x85 + +# evdev 130 (0x82), QKeyCode "props", number 0x86 +SunProps 0x86 + +# evdev 131 (0x83), QKeyCode "undo", number 0x87 +Undo 0x87 + +# evdev 132 (0x84), QKeyCode "front", number 0x8c +SunFront 0x8c + +# evdev 133 (0x85), QKeyCode "copy", number 0xf8 +XF86Copy 0xf8 + +# evdev 134 (0x86), QKeyCode "open", number 0x64 +XF86Open 0x64 + +# evdev 135 (0x87), QKeyCode "paste", number 0x65 +XF86Paste 0x65 + +# evdev 136 (0x88), QKeyCode "find", number 0xc1 +Find 0xc1 + +# evdev 137 (0x89), QKeyCode "cut", number 0xbc +XF86Cut 0xbc + +# evdev 138 (0x8a), QKeyCode "help", number 0xf5 +Help 0xf5 + +# evdev 139 (0x8b), QKeyCode "menu", number 0x9e +XF86MenuKB 0x9e + +# evdev 140 (0x8c), QKeyCode "calculator", number 0xa1 +XF86Calculator 0xa1 + +# evdev 141 (0x8d): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 142 (0x8e), QKeyCode "sleep", number 0xdf +XF86Sleep 0xdf + +# evdev 143 (0x8f), QKeyCode "wake", number 0xe3 +XF86WakeUp 0xe3 + +# evdev 144 (0x90): no evdev -> QKeyCode mapping (xkb keysym XF86Explorer) + +# evdev 145 (0x91): no evdev -> QKeyCode mapping (xkb keysym XF86Send) + +# evdev 146 (0x92): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 147 (0x93): no evdev -> QKeyCode mapping (xkb keysym XF86Xfer) + +# evdev 148 (0x94): no evdev -> QKeyCode mapping (xkb keysym XF86Launch1) + +# evdev 149 (0x95): no evdev -> QKeyCode mapping (xkb keysym XF86Launch2) + +# evdev 150 (0x96): no evdev -> QKeyCode mapping (xkb keysym XF86WWW) + +# evdev 151 (0x97): no evdev -> QKeyCode mapping (xkb keysym XF86DOS) + +# evdev 152 (0x98): no evdev -> QKeyCode mapping (xkb keysym XF86ScreenSaver) + +# evdev 153 (0x99): no evdev -> QKeyCode mapping (xkb keysym XF86RotateWindows) + +# evdev 154 (0x9a): no evdev -> QKeyCode mapping (xkb keysym XF86TaskPane) + +# evdev 155 (0x9b), QKeyCode "mail", number 0xec +XF86Mail 0xec + +# evdev 156 (0x9c), QKeyCode "ac_bookmarks", number 0xe6 +XF86Favorites 0xe6 + +# evdev 157 (0x9d), QKeyCode "computer", number 0xeb +XF86MyComputer 0xeb + +# evdev 158 (0x9e), QKeyCode "ac_back", number 0xea +XF86Back 0xea + +# evdev 159 (0x9f), QKeyCode "ac_forward", number 0xe9 +XF86Forward 0xe9 + +# evdev 160 (0xa0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 161 (0xa1): no evdev -> QKeyCode mapping (xkb keysym XF86Eject) + +# evdev 162 (0xa2): no evdev -> QKeyCode mapping (xkb keysym XF86Eject) + +# evdev 163 (0xa3), QKeyCode "audionext", number 0x99 +XF86AudioNext 0x99 + +# evdev 164 (0xa4), QKeyCode "audioplay", number 0xa2 +XF86AudioPlay 0xa2 +XF86AudioPause 0xa2 shift + +# evdev 165 (0xa5), QKeyCode "audioprev", number 0x90 +XF86AudioPrev 0x90 + +# evdev 166 (0xa6), QKeyCode "audiostop", number 0xa4 +XF86AudioStop 0xa4 +XF86Eject 0xa4 shift + +# evdev 167 (0xa7): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRecord) + +# evdev 168 (0xa8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRewind) + +# evdev 169 (0xa9): no evdev -> QKeyCode mapping (xkb keysym XF86Phone) + +# evdev 170 (0xaa): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 171 (0xab): no evdev -> QKeyCode mapping (xkb keysym XF86Tools) + +# evdev 172 (0xac), QKeyCode "ac_home", number 0xb2 +XF86HomePage 0xb2 + +# evdev 173 (0xad), QKeyCode "ac_refresh", number 0xe7 +XF86Reload 0xe7 + +# evdev 174 (0xae): no evdev -> QKeyCode mapping (xkb keysym XF86Close) + +# evdev 175 (0xaf): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 176 (0xb0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 177 (0xb1): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollUp) + +# evdev 178 (0xb2): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollDown) + +# evdev 179 (0xb3): no evdev -> QKeyCode mapping (xkb keysym parenleft) + +# evdev 180 (0xb4): no evdev -> QKeyCode mapping (xkb keysym parenright) + +# evdev 181 (0xb5): no evdev -> QKeyCode mapping (xkb keysym XF86New) + +# evdev 182 (0xb6): no evdev -> QKeyCode mapping (xkb keysym Redo) + +# evdev 183 (0xb7): no evdev -> QKeyCode mapping (xkb keysym XF86Tools) + +# evdev 184 (0xb8): no evdev -> QKeyCode mapping (xkb keysym XF86Launch5) + +# evdev 185 (0xb9): no evdev -> QKeyCode mapping (xkb keysym XF86Launch6) + +# evdev 186 (0xba): no evdev -> QKeyCode mapping (xkb keysym XF86Launch7) + +# evdev 187 (0xbb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch8) + +# evdev 188 (0xbc): no evdev -> QKeyCode mapping (xkb keysym XF86Launch9) + +# evdev 189 (0xbd): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 190 (0xbe): no evdev -> QKeyCode mapping (xkb keysym XF86AudioMicMute) + +# evdev 191 (0xbf): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadToggle) + +# evdev 192 (0xc0): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOn) + +# evdev 193 (0xc1): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOff) + +# evdev 194 (0xc2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 195 (0xc3): no evdev -> QKeyCode mapping (xkb keysym Mode_switch) + +# evdev 196 (0xc4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 197 (0xc5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 198 (0xc6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 199 (0xc7): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 200 (0xc8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay) + +# evdev 201 (0xc9): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPause) + +# evdev 202 (0xca): no evdev -> QKeyCode mapping (xkb keysym XF86Launch3) + +# evdev 203 (0xcb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch4) + +# evdev 204 (0xcc): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchB) + +# evdev 205 (0xcd): no evdev -> QKeyCode mapping (xkb keysym XF86Suspend) + +# evdev 206 (0xce): no evdev -> QKeyCode mapping (xkb keysym XF86Close) + +# evdev 207 (0xcf): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay) + +# evdev 208 (0xd0): no evdev -> QKeyCode mapping (xkb keysym XF86AudioForward) + +# evdev 209 (0xd1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 210 (0xd2): no evdev -> QKeyCode mapping (xkb keysym Print) + +# evdev 211 (0xd3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 212 (0xd4): no evdev -> QKeyCode mapping (xkb keysym XF86WebCam) + +# evdev 213 (0xd5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 214 (0xd6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 215 (0xd7): no evdev -> QKeyCode mapping (xkb keysym XF86Mail) + +# evdev 216 (0xd8): no evdev -> QKeyCode mapping (xkb keysym XF86Messenger) + +# evdev 217 (0xd9): no evdev -> QKeyCode mapping (xkb keysym XF86Search) + +# evdev 218 (0xda): no evdev -> QKeyCode mapping (xkb keysym XF86Go) + +# evdev 219 (0xdb): no evdev -> QKeyCode mapping (xkb keysym XF86Finance) + +# evdev 220 (0xdc): no evdev -> QKeyCode mapping (xkb keysym XF86Game) + +# evdev 221 (0xdd): no evdev -> QKeyCode mapping (xkb keysym XF86Shop) + +# evdev 222 (0xde): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 223 (0xdf): no evdev -> QKeyCode mapping (xkb keysym Cancel) + +# evdev 224 (0xe0): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessDown) + +# evdev 225 (0xe1): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessUp) + +# evdev 226 (0xe2), QKeyCode "mediaselect", number 0xed +XF86AudioMedia 0xed + +# evdev 227 (0xe3): no evdev -> QKeyCode mapping (xkb keysym XF86Display) + +# evdev 228 (0xe4): no evdev -> QKeyCode mapping (xkb keysym XF86KbdLightOnOff) + +# evdev 229 (0xe5): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessDown) + +# evdev 230 (0xe6): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessUp) + +# evdev 231 (0xe7): no evdev -> QKeyCode mapping (xkb keysym XF86Send) + +# evdev 232 (0xe8): no evdev -> QKeyCode mapping (xkb keysym XF86Reply) + +# evdev 233 (0xe9): no evdev -> QKeyCode mapping (xkb keysym XF86MailForward) + +# evdev 234 (0xea): no evdev -> QKeyCode mapping (xkb keysym XF86Save) + +# evdev 235 (0xeb): no evdev -> QKeyCode mapping (xkb keysym XF86Documents) + +# evdev 236 (0xec): no evdev -> QKeyCode mapping (xkb keysym XF86Battery) + +# evdev 237 (0xed): no evdev -> QKeyCode mapping (xkb keysym XF86Bluetooth) + +# evdev 238 (0xee): no evdev -> QKeyCode mapping (xkb keysym XF86WLAN) + +# evdev 239 (0xef): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 240 (0xf0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 241 (0xf1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 242 (0xf2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 243 (0xf3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 244 (0xf4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 245 (0xf5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 246 (0xf6): no evdev -> QKeyCode mapping (xkb keysym Invalid) + +# evdev 247 (0xf7): no evdev -> QKeyCode mapping (xkb keysym Invalid) + +# +# quirks section start +# +# Sometimes multiple keysyms map to the same keycodes. +# The keycode -> keysym lookup finds only one of the +# keysyms. So append them here. +# + +Print 0x54 +Sys_Req 0x54 +Execute 0x54 +KP_Decimal 0x53 numlock +KP_Separator 0x53 numlock +Alt_R 0xb8 +ISO_Level3_Shift 0xb8 +Mode_switch 0xb8 + +# quirks section end diff --git a/app/src/main/assets/roms/keymaps/ru b/app/src/main/assets/roms/keymaps/ru new file mode 100644 index 0000000..9502ba1 --- /dev/null +++ b/app/src/main/assets/roms/keymaps/ru @@ -0,0 +1,754 @@ +# +# generated by qemu-keymap +# model : pc105 +# layout : ru +# variant : - +# options : - + +# name: "Russian" + +# modifiers +# 0: Shift +# 1: Lock +# 2: Control +# 3: Mod1 +# 4: Mod2 +# 5: Mod3 +# 6: Mod4 +# 7: Mod5 +# 8: NumLock +# 9: Alt +# 10: LevelThree +# 11: LAlt +# 12: RAlt +# 13: RControl +# 14: LControl +# 15: ScrollLock +# 16: LevelFive +# 17: AltGr +# 18: Meta +# 19: Super +# 20: Hyper + +# evdev 1 (0x1), QKeyCode "esc", number 0x1 +Escape 0x01 + +# evdev 2 (0x2), QKeyCode "1", number 0x2 +1 0x02 +exclam 0x02 shift + +# evdev 3 (0x3), QKeyCode "2", number 0x3 +2 0x03 +quotedbl 0x03 shift + +# evdev 4 (0x4), QKeyCode "3", number 0x4 +3 0x04 +numerosign 0x04 shift + +# evdev 5 (0x5), QKeyCode "4", number 0x5 +4 0x05 +semicolon 0x05 shift + +# evdev 6 (0x6), QKeyCode "5", number 0x6 +5 0x06 +percent 0x06 shift + +# evdev 7 (0x7), QKeyCode "6", number 0x7 +6 0x07 +colon 0x07 shift + +# evdev 8 (0x8), QKeyCode "7", number 0x8 +7 0x08 +question 0x08 shift + +# evdev 9 (0x9), QKeyCode "8", number 0x9 +8 0x09 +asterisk 0x09 shift +U20BD 0x09 altgr + +# evdev 10 (0xa), QKeyCode "9", number 0xa +9 0x0a +parenleft 0x0a shift + +# evdev 11 (0xb), QKeyCode "0", number 0xb +0 0x0b +parenright 0x0b shift + +# evdev 12 (0xc), QKeyCode "minus", number 0xc +minus 0x0c +underscore 0x0c shift + +# evdev 13 (0xd), QKeyCode "equal", number 0xd +equal 0x0d +plus 0x0d shift + +# evdev 14 (0xe), QKeyCode "backspace", number 0xe +BackSpace 0x0e + +# evdev 15 (0xf), QKeyCode "tab", number 0xf +Tab 0x0f +ISO_Left_Tab 0x0f shift + +# evdev 16 (0x10), QKeyCode "q", number 0x10 +Cyrillic_shorti 0x10 +Cyrillic_SHORTI 0x10 shift + +# evdev 17 (0x11), QKeyCode "w", number 0x11 +Cyrillic_tse 0x11 +Cyrillic_TSE 0x11 shift + +# evdev 18 (0x12), QKeyCode "e", number 0x12 +Cyrillic_u 0x12 +Cyrillic_U 0x12 shift + +# evdev 19 (0x13), QKeyCode "r", number 0x13 +Cyrillic_ka 0x13 +Cyrillic_KA 0x13 shift + +# evdev 20 (0x14), QKeyCode "t", number 0x14 +Cyrillic_ie 0x14 +Cyrillic_IE 0x14 shift + +# evdev 21 (0x15), QKeyCode "y", number 0x15 +Cyrillic_en 0x15 +Cyrillic_EN 0x15 shift + +# evdev 22 (0x16), QKeyCode "u", number 0x16 +Cyrillic_ghe 0x16 +Cyrillic_GHE 0x16 shift + +# evdev 23 (0x17), QKeyCode "i", number 0x17 +Cyrillic_sha 0x17 +Cyrillic_SHA 0x17 shift + +# evdev 24 (0x18), QKeyCode "o", number 0x18 +Cyrillic_shcha 0x18 +Cyrillic_SHCHA 0x18 shift + +# evdev 25 (0x19), QKeyCode "p", number 0x19 +Cyrillic_ze 0x19 +Cyrillic_ZE 0x19 shift + +# evdev 26 (0x1a), QKeyCode "bracket_left", number 0x1a +Cyrillic_ha 0x1a +Cyrillic_HA 0x1a shift + +# evdev 27 (0x1b), QKeyCode "bracket_right", number 0x1b +Cyrillic_hardsign 0x1b +Cyrillic_HARDSIGN 0x1b shift + +# evdev 28 (0x1c), QKeyCode "ret", number 0x1c +Return 0x1c + +# evdev 29 (0x1d), QKeyCode "ctrl", number 0x1d +Control_L 0x1d + +# evdev 30 (0x1e), QKeyCode "a", number 0x1e +Cyrillic_ef 0x1e +Cyrillic_EF 0x1e shift + +# evdev 31 (0x1f), QKeyCode "s", number 0x1f +Cyrillic_yeru 0x1f +Cyrillic_YERU 0x1f shift + +# evdev 32 (0x20), QKeyCode "d", number 0x20 +Cyrillic_ve 0x20 +Cyrillic_VE 0x20 shift + +# evdev 33 (0x21), QKeyCode "f", number 0x21 +Cyrillic_a 0x21 +Cyrillic_A 0x21 shift + +# evdev 34 (0x22), QKeyCode "g", number 0x22 +Cyrillic_pe 0x22 +Cyrillic_PE 0x22 shift + +# evdev 35 (0x23), QKeyCode "h", number 0x23 +Cyrillic_er 0x23 +Cyrillic_ER 0x23 shift + +# evdev 36 (0x24), QKeyCode "j", number 0x24 +Cyrillic_o 0x24 +Cyrillic_O 0x24 shift + +# evdev 37 (0x25), QKeyCode "k", number 0x25 +Cyrillic_el 0x25 +Cyrillic_EL 0x25 shift + +# evdev 38 (0x26), QKeyCode "l", number 0x26 +Cyrillic_de 0x26 +Cyrillic_DE 0x26 shift + +# evdev 39 (0x27), QKeyCode "semicolon", number 0x27 +Cyrillic_zhe 0x27 +Cyrillic_ZHE 0x27 shift + +# evdev 40 (0x28), QKeyCode "apostrophe", number 0x28 +Cyrillic_e 0x28 +Cyrillic_E 0x28 shift + +# evdev 41 (0x29), QKeyCode "grave_accent", number 0x29 +Cyrillic_io 0x29 +Cyrillic_IO 0x29 shift + +# evdev 42 (0x2a), QKeyCode "shift", number 0x2a +Shift_L 0x2a + +# evdev 43 (0x2b), QKeyCode "backslash", number 0x2b +backslash 0x2b +slash 0x2b shift + +# evdev 44 (0x2c), QKeyCode "z", number 0x2c +Cyrillic_ya 0x2c +Cyrillic_YA 0x2c shift + +# evdev 45 (0x2d), QKeyCode "x", number 0x2d +Cyrillic_che 0x2d +Cyrillic_CHE 0x2d shift + +# evdev 46 (0x2e), QKeyCode "c", number 0x2e +Cyrillic_es 0x2e +Cyrillic_ES 0x2e shift + +# evdev 47 (0x2f), QKeyCode "v", number 0x2f +Cyrillic_em 0x2f +Cyrillic_EM 0x2f shift + +# evdev 48 (0x30), QKeyCode "b", number 0x30 +Cyrillic_i 0x30 +Cyrillic_I 0x30 shift + +# evdev 49 (0x31), QKeyCode "n", number 0x31 +Cyrillic_te 0x31 +Cyrillic_TE 0x31 shift + +# evdev 50 (0x32), QKeyCode "m", number 0x32 +Cyrillic_softsign 0x32 +Cyrillic_SOFTSIGN 0x32 shift + +# evdev 51 (0x33), QKeyCode "comma", number 0x33 +Cyrillic_be 0x33 +Cyrillic_BE 0x33 shift + +# evdev 52 (0x34), QKeyCode "dot", number 0x34 +Cyrillic_yu 0x34 +Cyrillic_YU 0x34 shift + +# evdev 53 (0x35), QKeyCode "slash", number 0x35 +period 0x35 +comma 0x35 shift + +# evdev 54 (0x36), QKeyCode "shift_r", number 0x36 +Shift_R 0x36 + +# evdev 55 (0x37), QKeyCode "kp_multiply", number 0x37 +KP_Multiply 0x37 + +# evdev 56 (0x38), QKeyCode "alt", number 0x38 +Alt_L 0x38 +Meta_L 0x38 shift + +# evdev 57 (0x39), QKeyCode "spc", number 0x39 +space 0x39 + +# evdev 58 (0x3a), QKeyCode "caps_lock", number 0x3a +Caps_Lock 0x3a + +# evdev 59 (0x3b), QKeyCode "f1", number 0x3b +F1 0x3b + +# evdev 60 (0x3c), QKeyCode "f2", number 0x3c +F2 0x3c + +# evdev 61 (0x3d), QKeyCode "f3", number 0x3d +F3 0x3d + +# evdev 62 (0x3e), QKeyCode "f4", number 0x3e +F4 0x3e + +# evdev 63 (0x3f), QKeyCode "f5", number 0x3f +F5 0x3f + +# evdev 64 (0x40), QKeyCode "f6", number 0x40 +F6 0x40 + +# evdev 65 (0x41), QKeyCode "f7", number 0x41 +F7 0x41 + +# evdev 66 (0x42), QKeyCode "f8", number 0x42 +F8 0x42 + +# evdev 67 (0x43), QKeyCode "f9", number 0x43 +F9 0x43 + +# evdev 68 (0x44), QKeyCode "f10", number 0x44 +F10 0x44 + +# evdev 69 (0x45), QKeyCode "num_lock", number 0x45 +Num_Lock 0x45 + +# evdev 70 (0x46), QKeyCode "scroll_lock", number 0x46 +Scroll_Lock 0x46 + +# evdev 71 (0x47), QKeyCode "kp_7", number 0x47 +KP_Home 0x47 +KP_7 0x47 numlock + +# evdev 72 (0x48), QKeyCode "kp_8", number 0x48 +KP_Up 0x48 +KP_8 0x48 numlock + +# evdev 73 (0x49), QKeyCode "kp_9", number 0x49 +KP_Prior 0x49 +KP_9 0x49 numlock + +# evdev 74 (0x4a), QKeyCode "kp_subtract", number 0x4a +KP_Subtract 0x4a + +# evdev 75 (0x4b), QKeyCode "kp_4", number 0x4b +KP_Left 0x4b +KP_4 0x4b numlock + +# evdev 76 (0x4c), QKeyCode "kp_5", number 0x4c +KP_Begin 0x4c +KP_5 0x4c numlock + +# evdev 77 (0x4d), QKeyCode "kp_6", number 0x4d +KP_Right 0x4d +KP_6 0x4d numlock + +# evdev 78 (0x4e), QKeyCode "kp_add", number 0x4e +KP_Add 0x4e + +# evdev 79 (0x4f), QKeyCode "kp_1", number 0x4f +KP_End 0x4f +KP_1 0x4f numlock + +# evdev 80 (0x50), QKeyCode "kp_2", number 0x50 +KP_Down 0x50 +KP_2 0x50 numlock + +# evdev 81 (0x51), QKeyCode "kp_3", number 0x51 +KP_Next 0x51 +KP_3 0x51 numlock + +# evdev 82 (0x52), QKeyCode "kp_0", number 0x52 +KP_Insert 0x52 +KP_0 0x52 numlock + +# evdev 83 (0x53), QKeyCode "kp_decimal", number 0x53 +KP_Delete 0x53 +KP_Separator 0x53 numlock + +# evdev 84 (0x54): no evdev -> QKeyCode mapping (xkb keysym ISO_Level3_Shift) + +# evdev 85 (0x55): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 86 (0x56), QKeyCode "less", number 0x56 +slash 0x56 +bar 0x56 shift +bar 0x56 altgr +brokenbar 0x56 shift altgr + +# evdev 87 (0x57), QKeyCode "f11", number 0x57 +F11 0x57 + +# evdev 88 (0x58), QKeyCode "f12", number 0x58 +F12 0x58 + +# evdev 89 (0x59), QKeyCode "ro", number 0x73 + +# evdev 90 (0x5a): no evdev -> QKeyCode mapping (xkb keysym Katakana) + +# evdev 91 (0x5b), QKeyCode "hiragana", number 0x77 +Hiragana 0x77 + +# evdev 92 (0x5c), QKeyCode "henkan", number 0x79 +Henkan_Mode 0x79 + +# evdev 93 (0x5d), QKeyCode "katakanahiragana", number 0x70 +Hiragana_Katakana 0x70 + +# evdev 94 (0x5e), QKeyCode "muhenkan", number 0x7b +Muhenkan 0x7b + +# evdev 95 (0x5f): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 96 (0x60), QKeyCode "kp_enter", number 0x9c +KP_Enter 0x9c + +# evdev 97 (0x61), QKeyCode "ctrl_r", number 0x9d +Control_R 0x9d + +# evdev 98 (0x62), QKeyCode "kp_divide", number 0xb5 +KP_Divide 0xb5 + +# evdev 99 (0x63), QKeyCode "sysrq", number 0x54 +Print 0x54 + +# evdev 100 (0x64), QKeyCode "alt_r", number 0xb8 +Alt_R 0xb8 +Meta_R 0xb8 shift + +# evdev 101 (0x65), QKeyCode "lf", number 0x5b +Linefeed 0x5b + +# evdev 102 (0x66), QKeyCode "home", number 0xc7 +Home 0xc7 + +# evdev 103 (0x67), QKeyCode "up", number 0xc8 +Up 0xc8 + +# evdev 104 (0x68), QKeyCode "pgup", number 0xc9 +Prior 0xc9 + +# evdev 105 (0x69), QKeyCode "left", number 0xcb +Left 0xcb + +# evdev 106 (0x6a), QKeyCode "right", number 0xcd +Right 0xcd + +# evdev 107 (0x6b), QKeyCode "end", number 0xcf +End 0xcf + +# evdev 108 (0x6c), QKeyCode "down", number 0xd0 +Down 0xd0 + +# evdev 109 (0x6d), QKeyCode "pgdn", number 0xd1 +Next 0xd1 + +# evdev 110 (0x6e), QKeyCode "insert", number 0xd2 +Insert 0xd2 + +# evdev 111 (0x6f), QKeyCode "delete", number 0xd3 +Delete 0xd3 + +# evdev 112 (0x70): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 113 (0x71), QKeyCode "audiomute", number 0xa0 +XF86AudioMute 0xa0 + +# evdev 114 (0x72), QKeyCode "volumedown", number 0xae +XF86AudioLowerVolume 0xae + +# evdev 115 (0x73), QKeyCode "volumeup", number 0xb0 +XF86AudioRaiseVolume 0xb0 + +# evdev 116 (0x74), QKeyCode "power", number 0xde +XF86PowerOff 0xde + +# evdev 117 (0x75), QKeyCode "kp_equals", number 0x59 +KP_Equal 0x59 + +# evdev 118 (0x76): no evdev -> QKeyCode mapping (xkb keysym plusminus) + +# evdev 119 (0x77), QKeyCode "pause", number 0xc6 +Pause 0xc6 + +# evdev 120 (0x78): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchA) + +# evdev 121 (0x79), QKeyCode "kp_comma", number 0x7e +KP_Decimal 0x7e + +# evdev 122 (0x7a): no evdev -> QKeyCode mapping (xkb keysym Hangul) + +# evdev 123 (0x7b): no evdev -> QKeyCode mapping (xkb keysym Hangul_Hanja) + +# evdev 124 (0x7c), QKeyCode "yen", number 0x7d + +# evdev 125 (0x7d), QKeyCode "meta_l", number 0xdb +Super_L 0xdb + +# evdev 126 (0x7e), QKeyCode "meta_r", number 0xdc +Super_R 0xdc + +# evdev 127 (0x7f), QKeyCode "compose", number 0xdd +Menu 0xdd + +# evdev 128 (0x80), QKeyCode "stop", number 0xe8 +Cancel 0xe8 + +# evdev 129 (0x81), QKeyCode "again", number 0x85 +Redo 0x85 + +# evdev 130 (0x82), QKeyCode "props", number 0x86 +SunProps 0x86 + +# evdev 131 (0x83), QKeyCode "undo", number 0x87 +Undo 0x87 + +# evdev 132 (0x84), QKeyCode "front", number 0x8c +SunFront 0x8c + +# evdev 133 (0x85), QKeyCode "copy", number 0xf8 +XF86Copy 0xf8 + +# evdev 134 (0x86), QKeyCode "open", number 0x64 +XF86Open 0x64 + +# evdev 135 (0x87), QKeyCode "paste", number 0x65 +XF86Paste 0x65 + +# evdev 136 (0x88), QKeyCode "find", number 0xc1 +Find 0xc1 + +# evdev 137 (0x89), QKeyCode "cut", number 0xbc +XF86Cut 0xbc + +# evdev 138 (0x8a), QKeyCode "help", number 0xf5 +Help 0xf5 + +# evdev 139 (0x8b), QKeyCode "menu", number 0x9e +XF86MenuKB 0x9e + +# evdev 140 (0x8c), QKeyCode "calculator", number 0xa1 +XF86Calculator 0xa1 + +# evdev 141 (0x8d): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 142 (0x8e), QKeyCode "sleep", number 0xdf +XF86Sleep 0xdf + +# evdev 143 (0x8f), QKeyCode "wake", number 0xe3 +XF86WakeUp 0xe3 + +# evdev 144 (0x90): no evdev -> QKeyCode mapping (xkb keysym XF86Explorer) + +# evdev 145 (0x91): no evdev -> QKeyCode mapping (xkb keysym XF86Send) + +# evdev 146 (0x92): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 147 (0x93): no evdev -> QKeyCode mapping (xkb keysym XF86Xfer) + +# evdev 148 (0x94): no evdev -> QKeyCode mapping (xkb keysym XF86Launch1) + +# evdev 149 (0x95): no evdev -> QKeyCode mapping (xkb keysym XF86Launch2) + +# evdev 150 (0x96): no evdev -> QKeyCode mapping (xkb keysym XF86WWW) + +# evdev 151 (0x97): no evdev -> QKeyCode mapping (xkb keysym XF86DOS) + +# evdev 152 (0x98): no evdev -> QKeyCode mapping (xkb keysym XF86ScreenSaver) + +# evdev 153 (0x99): no evdev -> QKeyCode mapping (xkb keysym XF86RotateWindows) + +# evdev 154 (0x9a): no evdev -> QKeyCode mapping (xkb keysym XF86TaskPane) + +# evdev 155 (0x9b), QKeyCode "mail", number 0xec +XF86Mail 0xec + +# evdev 156 (0x9c), QKeyCode "ac_bookmarks", number 0xe6 +XF86Favorites 0xe6 + +# evdev 157 (0x9d), QKeyCode "computer", number 0xeb +XF86MyComputer 0xeb + +# evdev 158 (0x9e), QKeyCode "ac_back", number 0xea +XF86Back 0xea + +# evdev 159 (0x9f), QKeyCode "ac_forward", number 0xe9 +XF86Forward 0xe9 + +# evdev 160 (0xa0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 161 (0xa1): no evdev -> QKeyCode mapping (xkb keysym XF86Eject) + +# evdev 162 (0xa2): no evdev -> QKeyCode mapping (xkb keysym XF86Eject) + +# evdev 163 (0xa3), QKeyCode "audionext", number 0x99 +XF86AudioNext 0x99 + +# evdev 164 (0xa4), QKeyCode "audioplay", number 0xa2 +XF86AudioPlay 0xa2 +XF86AudioPause 0xa2 shift + +# evdev 165 (0xa5), QKeyCode "audioprev", number 0x90 +XF86AudioPrev 0x90 + +# evdev 166 (0xa6), QKeyCode "audiostop", number 0xa4 +XF86AudioStop 0xa4 +XF86Eject 0xa4 shift + +# evdev 167 (0xa7): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRecord) + +# evdev 168 (0xa8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRewind) + +# evdev 169 (0xa9): no evdev -> QKeyCode mapping (xkb keysym XF86Phone) + +# evdev 170 (0xaa): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 171 (0xab): no evdev -> QKeyCode mapping (xkb keysym XF86Tools) + +# evdev 172 (0xac), QKeyCode "ac_home", number 0xb2 +XF86HomePage 0xb2 + +# evdev 173 (0xad), QKeyCode "ac_refresh", number 0xe7 +XF86Reload 0xe7 + +# evdev 174 (0xae): no evdev -> QKeyCode mapping (xkb keysym XF86Close) + +# evdev 175 (0xaf): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 176 (0xb0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 177 (0xb1): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollUp) + +# evdev 178 (0xb2): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollDown) + +# evdev 179 (0xb3): no evdev -> QKeyCode mapping (xkb keysym parenleft) + +# evdev 180 (0xb4): no evdev -> QKeyCode mapping (xkb keysym parenright) + +# evdev 181 (0xb5): no evdev -> QKeyCode mapping (xkb keysym XF86New) + +# evdev 182 (0xb6): no evdev -> QKeyCode mapping (xkb keysym Redo) + +# evdev 183 (0xb7): no evdev -> QKeyCode mapping (xkb keysym XF86Tools) + +# evdev 184 (0xb8): no evdev -> QKeyCode mapping (xkb keysym XF86Launch5) + +# evdev 185 (0xb9): no evdev -> QKeyCode mapping (xkb keysym XF86Launch6) + +# evdev 186 (0xba): no evdev -> QKeyCode mapping (xkb keysym XF86Launch7) + +# evdev 187 (0xbb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch8) + +# evdev 188 (0xbc): no evdev -> QKeyCode mapping (xkb keysym XF86Launch9) + +# evdev 189 (0xbd): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 190 (0xbe): no evdev -> QKeyCode mapping (xkb keysym XF86AudioMicMute) + +# evdev 191 (0xbf): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadToggle) + +# evdev 192 (0xc0): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOn) + +# evdev 193 (0xc1): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOff) + +# evdev 194 (0xc2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 195 (0xc3): no evdev -> QKeyCode mapping (xkb keysym Mode_switch) + +# evdev 196 (0xc4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 197 (0xc5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 198 (0xc6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 199 (0xc7): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 200 (0xc8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay) + +# evdev 201 (0xc9): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPause) + +# evdev 202 (0xca): no evdev -> QKeyCode mapping (xkb keysym XF86Launch3) + +# evdev 203 (0xcb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch4) + +# evdev 204 (0xcc): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchB) + +# evdev 205 (0xcd): no evdev -> QKeyCode mapping (xkb keysym XF86Suspend) + +# evdev 206 (0xce): no evdev -> QKeyCode mapping (xkb keysym XF86Close) + +# evdev 207 (0xcf): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay) + +# evdev 208 (0xd0): no evdev -> QKeyCode mapping (xkb keysym XF86AudioForward) + +# evdev 209 (0xd1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 210 (0xd2): no evdev -> QKeyCode mapping (xkb keysym Print) + +# evdev 211 (0xd3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 212 (0xd4): no evdev -> QKeyCode mapping (xkb keysym XF86WebCam) + +# evdev 213 (0xd5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 214 (0xd6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 215 (0xd7): no evdev -> QKeyCode mapping (xkb keysym XF86Mail) + +# evdev 216 (0xd8): no evdev -> QKeyCode mapping (xkb keysym XF86Messenger) + +# evdev 217 (0xd9): no evdev -> QKeyCode mapping (xkb keysym XF86Search) + +# evdev 218 (0xda): no evdev -> QKeyCode mapping (xkb keysym XF86Go) + +# evdev 219 (0xdb): no evdev -> QKeyCode mapping (xkb keysym XF86Finance) + +# evdev 220 (0xdc): no evdev -> QKeyCode mapping (xkb keysym XF86Game) + +# evdev 221 (0xdd): no evdev -> QKeyCode mapping (xkb keysym XF86Shop) + +# evdev 222 (0xde): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 223 (0xdf): no evdev -> QKeyCode mapping (xkb keysym Cancel) + +# evdev 224 (0xe0): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessDown) + +# evdev 225 (0xe1): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessUp) + +# evdev 226 (0xe2), QKeyCode "mediaselect", number 0xed +XF86AudioMedia 0xed + +# evdev 227 (0xe3): no evdev -> QKeyCode mapping (xkb keysym XF86Display) + +# evdev 228 (0xe4): no evdev -> QKeyCode mapping (xkb keysym XF86KbdLightOnOff) + +# evdev 229 (0xe5): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessDown) + +# evdev 230 (0xe6): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessUp) + +# evdev 231 (0xe7): no evdev -> QKeyCode mapping (xkb keysym XF86Send) + +# evdev 232 (0xe8): no evdev -> QKeyCode mapping (xkb keysym XF86Reply) + +# evdev 233 (0xe9): no evdev -> QKeyCode mapping (xkb keysym XF86MailForward) + +# evdev 234 (0xea): no evdev -> QKeyCode mapping (xkb keysym XF86Save) + +# evdev 235 (0xeb): no evdev -> QKeyCode mapping (xkb keysym XF86Documents) + +# evdev 236 (0xec): no evdev -> QKeyCode mapping (xkb keysym XF86Battery) + +# evdev 237 (0xed): no evdev -> QKeyCode mapping (xkb keysym XF86Bluetooth) + +# evdev 238 (0xee): no evdev -> QKeyCode mapping (xkb keysym XF86WLAN) + +# evdev 239 (0xef): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 240 (0xf0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 241 (0xf1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 242 (0xf2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 243 (0xf3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 244 (0xf4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 245 (0xf5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 246 (0xf6): no evdev -> QKeyCode mapping (xkb keysym Invalid) + +# evdev 247 (0xf7): no evdev -> QKeyCode mapping (xkb keysym Invalid) + +# +# quirks section start +# +# Sometimes multiple keysyms map to the same keycodes. +# The keycode -> keysym lookup finds only one of the +# keysyms. So append them here. +# + +Print 0x54 +Sys_Req 0x54 +Execute 0x54 +KP_Decimal 0x53 numlock +KP_Separator 0x53 numlock +Alt_R 0xb8 +ISO_Level3_Shift 0xb8 +Mode_switch 0xb8 + +# quirks section end diff --git a/app/src/main/assets/roms/keymaps/sl b/app/src/main/assets/roms/keymaps/sl new file mode 100644 index 0000000..73eb956 --- /dev/null +++ b/app/src/main/assets/roms/keymaps/sl @@ -0,0 +1,285 @@ +# generated from XKB map sl + +Shift_R 0x36 +Shift_L 0x2a + +Alt_R 0xb8 +Mode_switch 0xb8 +ISO_Level3_Shift 0xb8 +Alt_L 0x38 + +Control_R 0x9d +Control_L 0x1d + +# Translate Super to Windows keys. +# This is hardcoded. See documentation for details. +Super_R 0xdc +Super_L 0xdb + +# Translate Menu to the Windows Application key. +Menu 0xdd + +# +# Top row +# +1 0x2 +2 0x3 +3 0x4 +4 0x5 +5 0x6 +6 0x7 +7 0x8 +8 0x9 +9 0xa +0 0xb +BackSpace 0xe + +# +# QWERTY first row +# +Tab 0xf localstate +ISO_Left_Tab 0xf shift +q 0x10 addupper +w 0x11 addupper +e 0x12 addupper +r 0x13 addupper +t 0x14 addupper +y 0x15 addupper +u 0x16 addupper +i 0x17 addupper +o 0x18 addupper +p 0x19 addupper + +# +# QWERTY second row +# +a 0x1e addupper +s 0x1f addupper +d 0x20 addupper +f 0x21 addupper +g 0x22 addupper +h 0x23 addupper +j 0x24 addupper +k 0x25 addupper +l 0x26 addupper +Return 0x1c localstate + +# +# QWERTY third row +# +z 0x2c addupper +x 0x2d addupper +c 0x2e addupper +v 0x2f addupper +b 0x30 addupper +n 0x31 addupper +m 0x32 addupper + +space 0x39 localstate + +less 0x56 +greater 0x56 shift +bar 0x56 altgr +brokenbar 0x56 shift altgr + +# +# Esc and Function keys +# +Escape 0x1 localstate +F1 0x3b localstate +F2 0x3c localstate +F3 0x3d localstate +F4 0x3e localstate +F5 0x3f localstate +F6 0x40 localstate +F7 0x41 localstate +F8 0x42 localstate +F9 0x43 localstate +F10 0x44 localstate +F11 0x57 localstate +F12 0x58 localstate + +# Printscreen, Scrollock and Pause +# Printscreen really requires four scancodes (0xe0, 0x2a, 0xe0, 0x37), +# but (0xe0, 0x37) seems to work. +Print 0xb7 localstate +Sys_Req 0xb7 localstate +Execute 0xb7 localstate +Scroll_Lock 0x46 + +# +# Insert - PgDown +# +Insert 0xd2 localstate +Delete 0xd3 localstate +Home 0xc7 localstate +End 0xcf localstate +Page_Up 0xc9 localstate +Page_Down 0xd1 localstate + +# +# Arrow keys +# +Left 0xcb localstate +Up 0xc8 localstate +Down 0xd0 localstate +Right 0xcd localstate + +# +# Numpad +# +Num_Lock 0x45 +KP_Divide 0xb5 +KP_Multiply 0x37 +KP_Subtract 0x4a +KP_Add 0x4e +KP_Enter 0x9c + +KP_Decimal 0x53 numlock +KP_Separator 0x53 numlock +KP_Delete 0x53 + +KP_0 0x52 numlock +KP_Insert 0x52 + +KP_1 0x4f numlock +KP_End 0x4f + +KP_2 0x50 numlock +KP_Down 0x50 + +KP_3 0x51 numlock +KP_Next 0x51 + +KP_4 0x4b numlock +KP_Left 0x4b + +KP_5 0x4c numlock +KP_Begin 0x4c + +KP_6 0x4d numlock +KP_Right 0x4d + +KP_7 0x47 numlock +KP_Home 0x47 + +KP_8 0x48 numlock +KP_Up 0x48 + +KP_9 0x49 numlock +KP_Prior 0x49 + +Caps_Lock 0x3a +# +# Inhibited keys +# +Multi_key 0x0 inhibit + +map 0x424 +exclam 0x02 shift +asciitilde 0x02 altgr +dead_tilde 0x02 shift altgr +quotedbl 0x03 shift +dead_caron 0x03 altgr +caron 0x03 shift altgr +numbersign 0x04 shift +asciicircum 0x04 altgr +dead_circumflex 0x04 shift altgr +dollar 0x05 shift +dead_breve 0x05 altgr +breve 0x05 shift altgr +percent 0x06 shift +degree 0x06 altgr +dead_abovering 0x06 shift altgr +ampersand 0x07 shift +dead_ogonek 0x07 altgr +ogonek 0x07 shift altgr +slash 0x08 shift +grave 0x08 altgr +dead_grave 0x08 shift altgr +parenleft 0x09 shift +dead_abovedot 0x09 altgr +abovedot 0x09 shift altgr +parenright 0x0a shift +dead_acute 0x0a altgr +equal 0x0b shift +dead_doubleacute 0x0b altgr +doubleacute 0x0b shift altgr +apostrophe 0x0c +question 0x0c shift +dead_diaeresis 0x0c altgr +diaeresis 0x0c shift altgr +plus 0x0d +asterisk 0x0d shift +dead_cedilla 0x0d altgr +cedilla 0x0d shift altgr +backslash 0x10 altgr +Greek_OMEGA 0x10 shift altgr +bar 0x11 altgr +Lstroke 0x11 shift altgr +EuroSign 0x12 altgr +paragraph 0x13 altgr +registered 0x13 shift altgr +tslash 0x14 altgr +Tslash 0x14 shift altgr +z 0x15 addupper +leftarrow 0x15 altgr +yen 0x15 shift altgr +downarrow 0x16 altgr +uparrow 0x16 shift altgr +rightarrow 0x17 altgr +idotless 0x17 shift altgr +oslash 0x18 altgr +Ooblique 0x18 shift altgr +thorn 0x19 altgr +THORN 0x19 shift altgr +scaron 0x1a +Scaron 0x1a shift +division 0x1a altgr +dstroke 0x1b +Dstroke 0x1b shift +multiply 0x1b altgr +dead_macron 0x1b shift altgr +ae 0x1e altgr +AE 0x1e shift altgr +ssharp 0x1f altgr +section 0x1f shift altgr +eth 0x20 altgr +ETH 0x20 shift altgr +bracketleft 0x21 altgr +ordfeminine 0x21 shift altgr +bracketright 0x22 altgr +ENG 0x22 shift altgr +hstroke 0x23 altgr +Hstroke 0x23 shift altgr +lstroke 0x25 altgr +Lstroke 0x26 altgr +ccaron 0x27 +Ccaron 0x27 shift +cacute 0x28 +Cacute 0x28 shift +ssharp 0x28 altgr +dead_cedilla 0x29 +notsign 0x29 altgr +zcaron 0x2b +Zcaron 0x2b shift +currency 0x2b altgr +y 0x2c addupper +guillemotleft 0x2c altgr +guillemotright 0x2d altgr +cent 0x2e altgr +copyright 0x2e shift altgr +at 0x2f altgr +braceleft 0x30 altgr +braceright 0x31 altgr +section 0x32 altgr +masculine 0x32 shift altgr +comma 0x33 +semicolon 0x33 shift +horizconnector 0x33 altgr +period 0x34 +colon 0x34 shift +periodcentered 0x34 altgr +minus 0x35 +underscore 0x35 shift +dead_belowdot 0x35 altgr diff --git a/app/src/main/assets/roms/keymaps/sv b/app/src/main/assets/roms/keymaps/sv new file mode 100644 index 0000000..0717b71 --- /dev/null +++ b/app/src/main/assets/roms/keymaps/sv @@ -0,0 +1,255 @@ +map 0x0000041d + +Shift_R 0x36 +Shift_L 0x2a + +Alt_R 0xb8 +Mode_switch 0xb8 +ISO_Level3_Shift 0xb8 +Alt_L 0x38 + +Control_R 0x9d +Control_L 0x1d + +# Translate Super to Windows keys. +# This is hardcoded. See documentation for details. +Super_R 0xdc +Super_L 0xdb + +# Translate Menu to the Windows Application key. +Menu 0xdd + +# +# Top row +# +1 0x2 +2 0x3 +3 0x4 +4 0x5 +5 0x6 +6 0x7 +7 0x8 +8 0x9 +9 0xa +0 0xb +BackSpace 0xe + +# +# QWERTY first row +# +Tab 0xf localstate +ISO_Left_Tab 0xf shift +q 0x10 addupper +w 0x11 addupper +e 0x12 addupper +r 0x13 addupper +t 0x14 addupper +y 0x15 addupper +u 0x16 addupper +i 0x17 addupper +o 0x18 addupper +p 0x19 addupper + +# +# QWERTY second row +# +a 0x1e addupper +s 0x1f addupper +d 0x20 addupper +f 0x21 addupper +g 0x22 addupper +h 0x23 addupper +j 0x24 addupper +k 0x25 addupper +l 0x26 addupper +Return 0x1c localstate + +# +# QWERTY third row +# +z 0x2c addupper +x 0x2d addupper +c 0x2e addupper +v 0x2f addupper +b 0x30 addupper +n 0x31 addupper +m 0x32 addupper + +space 0x39 localstate + +less 0x56 +greater 0x56 shift +bar 0x56 altgr +brokenbar 0x56 shift altgr + +# +# Esc and Function keys +# +Escape 0x1 localstate +F1 0x3b localstate +F2 0x3c localstate +F3 0x3d localstate +F4 0x3e localstate +F5 0x3f localstate +F6 0x40 localstate +F7 0x41 localstate +F8 0x42 localstate +F9 0x43 localstate +F10 0x44 localstate +F11 0x57 localstate +F12 0x58 localstate + +# Printscreen, Scrollock and Pause +# Printscreen really requires four scancodes (0xe0, 0x2a, 0xe0, 0x37), +# but (0xe0, 0x37) seems to work. +Print 0xb7 localstate +Sys_Req 0xb7 localstate +Execute 0xb7 localstate +Scroll_Lock 0x46 + +# +# Insert - PgDown +# +Insert 0xd2 localstate +Delete 0xd3 localstate +Home 0xc7 localstate +End 0xcf localstate +Page_Up 0xc9 localstate +Page_Down 0xd1 localstate + +# +# Arrow keys +# +Left 0xcb localstate +Up 0xc8 localstate +Down 0xd0 localstate +Right 0xcd localstate + +# +# Numpad +# +Num_Lock 0x45 +KP_Divide 0xb5 +KP_Multiply 0x37 +KP_Subtract 0x4a +KP_Add 0x4e +KP_Enter 0x9c + +KP_Decimal 0x53 numlock +KP_Separator 0x53 numlock +KP_Delete 0x53 + +KP_0 0x52 numlock +KP_Insert 0x52 + +KP_1 0x4f numlock +KP_End 0x4f + +KP_2 0x50 numlock +KP_Down 0x50 + +KP_3 0x51 numlock +KP_Next 0x51 + +KP_4 0x4b numlock +KP_Left 0x4b + +KP_5 0x4c numlock +KP_Begin 0x4c + +KP_6 0x4d numlock +KP_Right 0x4d + +KP_7 0x47 numlock +KP_Home 0x47 + +KP_8 0x48 numlock +KP_Up 0x48 + +KP_9 0x49 numlock +KP_Prior 0x49 + +Caps_Lock 0x3a +# +# Inhibited keys +# +Multi_key 0x0 inhibit + +# +# Top row +# +section 0x29 +onehalf 0x29 shift + +# 1 +exclam 0x2 shift + +# 2 +quotedbl 0x3 shift +at 0x3 altgr + +# 3 +numbersign 0x4 shift +sterling 0x4 altgr +# 4 +currency 0x5 shift +dollar 0x5 altgr +# 5 +percent 0x6 shift +# 6 +ampersand 0x7 shift +# 7 +slash 0x8 shift +braceleft 0x8 altgr +# 8 +parenleft 0x9 shift +bracketleft 0x9 altgr +# 9 +parenright 0xa shift +bracketright 0xa altgr +# 0 +equal 0xb shift +braceright 0xb altgr + +plus 0xc +question 0xc shift +backslash 0xc altgr + +acute 0xd +dead_acute 0xd +grave 0xd shift +dead_grave 0xd shift + +# +# QWERTY first row +# +EuroSign 0x12 altgr +aring 0x1a +Aring 0x1a shift +dead_diaeresis 0x1b +dead_circumflex 0x1b shift +dead_tilde 0x1b altgr + +# +# QWERTY second row +# +odiaeresis 0x27 +Odiaeresis 0x27 shift +adiaeresis 0x28 +Adiaeresis 0x28 shift +apostrophe 0x2b +asterisk 0x2b shift + +# +# QWERTY third row +# +less 0x56 +greater 0x56 shift +bar 0x56 altgr +mu 0x32 altgr +comma 0x33 +semicolon 0x33 shift +period 0x34 +colon 0x34 shift +minus 0x35 +underscore 0x35 shift diff --git a/app/src/main/assets/roms/keymaps/th b/app/src/main/assets/roms/keymaps/th new file mode 100644 index 0000000..b8298d9 --- /dev/null +++ b/app/src/main/assets/roms/keymaps/th @@ -0,0 +1,753 @@ +# +# generated by qemu-keymap +# model : pc105 +# layout : th +# variant : - +# options : - + +# name: "Thai" + +# modifiers +# 0: Shift +# 1: Lock +# 2: Control +# 3: Mod1 +# 4: Mod2 +# 5: Mod3 +# 6: Mod4 +# 7: Mod5 +# 8: NumLock +# 9: Alt +# 10: LevelThree +# 11: LAlt +# 12: RAlt +# 13: RControl +# 14: LControl +# 15: ScrollLock +# 16: LevelFive +# 17: AltGr +# 18: Meta +# 19: Super +# 20: Hyper + +# evdev 1 (0x1), QKeyCode "esc", number 0x1 +Escape 0x01 + +# evdev 2 (0x2), QKeyCode "1", number 0x2 +Thai_lakkhangyao 0x02 +plus 0x02 shift + +# evdev 3 (0x3), QKeyCode "2", number 0x3 +slash 0x03 +Thai_leknung 0x03 shift + +# evdev 4 (0x4), QKeyCode "3", number 0x4 +minus 0x04 +Thai_leksong 0x04 shift + +# evdev 5 (0x5), QKeyCode "4", number 0x5 +Thai_phosamphao 0x05 +Thai_leksam 0x05 shift + +# evdev 6 (0x6), QKeyCode "5", number 0x6 +Thai_thothung 0x06 +Thai_leksi 0x06 shift + +# evdev 7 (0x7), QKeyCode "6", number 0x7 +Thai_sarau 0x07 +Thai_sarauu 0x07 shift + +# evdev 8 (0x8), QKeyCode "7", number 0x8 +Thai_saraue 0x08 +Thai_baht 0x08 shift + +# evdev 9 (0x9), QKeyCode "8", number 0x9 +Thai_khokhwai 0x09 +Thai_lekha 0x09 shift + +# evdev 10 (0xa), QKeyCode "9", number 0xa +Thai_totao 0x0a +Thai_lekhok 0x0a shift + +# evdev 11 (0xb), QKeyCode "0", number 0xb +Thai_chochan 0x0b +Thai_lekchet 0x0b shift + +# evdev 12 (0xc), QKeyCode "minus", number 0xc +Thai_khokhai 0x0c +Thai_lekpaet 0x0c shift + +# evdev 13 (0xd), QKeyCode "equal", number 0xd +Thai_chochang 0x0d +Thai_lekkao 0x0d shift + +# evdev 14 (0xe), QKeyCode "backspace", number 0xe +BackSpace 0x0e + +# evdev 15 (0xf), QKeyCode "tab", number 0xf +Tab 0x0f +ISO_Left_Tab 0x0f shift + +# evdev 16 (0x10), QKeyCode "q", number 0x10 +Thai_maiyamok 0x10 +Thai_leksun 0x10 shift + +# evdev 17 (0x11), QKeyCode "w", number 0x11 +Thai_saraaimaimalai 0x11 +quotedbl 0x11 shift + +# evdev 18 (0x12), QKeyCode "e", number 0x12 +Thai_saraam 0x12 +Thai_dochada 0x12 shift + +# evdev 19 (0x13), QKeyCode "r", number 0x13 +Thai_phophan 0x13 +Thai_thonangmontho 0x13 shift + +# evdev 20 (0x14), QKeyCode "t", number 0x14 +Thai_saraa 0x14 +Thai_thothong 0x14 shift + +# evdev 21 (0x15), QKeyCode "y", number 0x15 +Thai_maihanakat 0x15 +Thai_nikhahit 0x15 shift + +# evdev 22 (0x16), QKeyCode "u", number 0x16 +Thai_saraii 0x16 +Thai_maitri 0x16 shift + +# evdev 23 (0x17), QKeyCode "i", number 0x17 +Thai_rorua 0x17 +Thai_nonen 0x17 shift + +# evdev 24 (0x18), QKeyCode "o", number 0x18 +Thai_nonu 0x18 +Thai_paiyannoi 0x18 shift + +# evdev 25 (0x19), QKeyCode "p", number 0x19 +Thai_yoyak 0x19 +Thai_yoying 0x19 shift + +# evdev 26 (0x1a), QKeyCode "bracket_left", number 0x1a +Thai_bobaimai 0x1a +Thai_thothan 0x1a shift + +# evdev 27 (0x1b), QKeyCode "bracket_right", number 0x1b +Thai_loling 0x1b +comma 0x1b shift + +# evdev 28 (0x1c), QKeyCode "ret", number 0x1c +Return 0x1c + +# evdev 29 (0x1d), QKeyCode "ctrl", number 0x1d +Control_L 0x1d + +# evdev 30 (0x1e), QKeyCode "a", number 0x1e +Thai_fofan 0x1e +Thai_ru 0x1e shift + +# evdev 31 (0x1f), QKeyCode "s", number 0x1f +Thai_hohip 0x1f +Thai_khorakhang 0x1f shift + +# evdev 32 (0x20), QKeyCode "d", number 0x20 +Thai_kokai 0x20 +Thai_topatak 0x20 shift + +# evdev 33 (0x21), QKeyCode "f", number 0x21 +Thai_dodek 0x21 +Thai_sarao 0x21 shift + +# evdev 34 (0x22), QKeyCode "g", number 0x22 +Thai_sarae 0x22 +Thai_chochoe 0x22 shift + +# evdev 35 (0x23), QKeyCode "h", number 0x23 +Thai_maitho 0x23 +Thai_maitaikhu 0x23 shift + +# evdev 36 (0x24), QKeyCode "j", number 0x24 +Thai_maiek 0x24 +Thai_maichattawa 0x24 shift + +# evdev 37 (0x25), QKeyCode "k", number 0x25 +Thai_saraaa 0x25 +Thai_sorusi 0x25 shift + +# evdev 38 (0x26), QKeyCode "l", number 0x26 +Thai_sosua 0x26 +Thai_sosala 0x26 shift + +# evdev 39 (0x27), QKeyCode "semicolon", number 0x27 +Thai_wowaen 0x27 +Thai_soso 0x27 shift + +# evdev 40 (0x28), QKeyCode "apostrophe", number 0x28 +Thai_ngongu 0x28 +period 0x28 shift + +# evdev 41 (0x29), QKeyCode "grave_accent", number 0x29 +underscore 0x29 +percent 0x29 shift + +# evdev 42 (0x2a), QKeyCode "shift", number 0x2a +Shift_L 0x2a + +# evdev 43 (0x2b), QKeyCode "backslash", number 0x2b +Thai_khokhuat 0x2b +Thai_khokhon 0x2b shift + +# evdev 44 (0x2c), QKeyCode "z", number 0x2c +Thai_phophung 0x2c +parenleft 0x2c shift + +# evdev 45 (0x2d), QKeyCode "x", number 0x2d +Thai_popla 0x2d +parenright 0x2d shift + +# evdev 46 (0x2e), QKeyCode "c", number 0x2e +Thai_saraae 0x2e +Thai_choching 0x2e shift + +# evdev 47 (0x2f), QKeyCode "v", number 0x2f +Thai_oang 0x2f +Thai_honokhuk 0x2f shift + +# evdev 48 (0x30), QKeyCode "b", number 0x30 +Thai_sarai 0x30 +Thai_phinthu 0x30 shift + +# evdev 49 (0x31), QKeyCode "n", number 0x31 +Thai_sarauee 0x31 +Thai_thanthakhat 0x31 shift + +# evdev 50 (0x32), QKeyCode "m", number 0x32 +Thai_thothahan 0x32 +question 0x32 shift + +# evdev 51 (0x33), QKeyCode "comma", number 0x33 +Thai_moma 0x33 +Thai_thophuthao 0x33 shift + +# evdev 52 (0x34), QKeyCode "dot", number 0x34 +Thai_saraaimaimuan 0x34 +Thai_lochula 0x34 shift + +# evdev 53 (0x35), QKeyCode "slash", number 0x35 +Thai_fofa 0x35 +Thai_lu 0x35 shift + +# evdev 54 (0x36), QKeyCode "shift_r", number 0x36 +Shift_R 0x36 + +# evdev 55 (0x37), QKeyCode "kp_multiply", number 0x37 +KP_Multiply 0x37 + +# evdev 56 (0x38), QKeyCode "alt", number 0x38 +Alt_L 0x38 +Meta_L 0x38 shift + +# evdev 57 (0x39), QKeyCode "spc", number 0x39 +space 0x39 + +# evdev 58 (0x3a), QKeyCode "caps_lock", number 0x3a +Caps_Lock 0x3a + +# evdev 59 (0x3b), QKeyCode "f1", number 0x3b +F1 0x3b + +# evdev 60 (0x3c), QKeyCode "f2", number 0x3c +F2 0x3c + +# evdev 61 (0x3d), QKeyCode "f3", number 0x3d +F3 0x3d + +# evdev 62 (0x3e), QKeyCode "f4", number 0x3e +F4 0x3e + +# evdev 63 (0x3f), QKeyCode "f5", number 0x3f +F5 0x3f + +# evdev 64 (0x40), QKeyCode "f6", number 0x40 +F6 0x40 + +# evdev 65 (0x41), QKeyCode "f7", number 0x41 +F7 0x41 + +# evdev 66 (0x42), QKeyCode "f8", number 0x42 +F8 0x42 + +# evdev 67 (0x43), QKeyCode "f9", number 0x43 +F9 0x43 + +# evdev 68 (0x44), QKeyCode "f10", number 0x44 +F10 0x44 + +# evdev 69 (0x45), QKeyCode "num_lock", number 0x45 +Num_Lock 0x45 + +# evdev 70 (0x46), QKeyCode "scroll_lock", number 0x46 +Scroll_Lock 0x46 + +# evdev 71 (0x47), QKeyCode "kp_7", number 0x47 +KP_Home 0x47 +KP_7 0x47 numlock + +# evdev 72 (0x48), QKeyCode "kp_8", number 0x48 +KP_Up 0x48 +KP_8 0x48 numlock + +# evdev 73 (0x49), QKeyCode "kp_9", number 0x49 +KP_Prior 0x49 +KP_9 0x49 numlock + +# evdev 74 (0x4a), QKeyCode "kp_subtract", number 0x4a +KP_Subtract 0x4a + +# evdev 75 (0x4b), QKeyCode "kp_4", number 0x4b +KP_Left 0x4b +KP_4 0x4b numlock + +# evdev 76 (0x4c), QKeyCode "kp_5", number 0x4c +KP_Begin 0x4c +KP_5 0x4c numlock + +# evdev 77 (0x4d), QKeyCode "kp_6", number 0x4d +KP_Right 0x4d +KP_6 0x4d numlock + +# evdev 78 (0x4e), QKeyCode "kp_add", number 0x4e +KP_Add 0x4e + +# evdev 79 (0x4f), QKeyCode "kp_1", number 0x4f +KP_End 0x4f +KP_1 0x4f numlock + +# evdev 80 (0x50), QKeyCode "kp_2", number 0x50 +KP_Down 0x50 +KP_2 0x50 numlock + +# evdev 81 (0x51), QKeyCode "kp_3", number 0x51 +KP_Next 0x51 +KP_3 0x51 numlock + +# evdev 82 (0x52), QKeyCode "kp_0", number 0x52 +KP_Insert 0x52 +KP_0 0x52 numlock + +# evdev 83 (0x53), QKeyCode "kp_decimal", number 0x53 +KP_Delete 0x53 +KP_Decimal 0x53 numlock + +# evdev 84 (0x54): no evdev -> QKeyCode mapping (xkb keysym ISO_Level3_Shift) + +# evdev 85 (0x55): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 86 (0x56), QKeyCode "less", number 0x56 +less 0x56 +greater 0x56 shift +bar 0x56 altgr +brokenbar 0x56 shift altgr + +# evdev 87 (0x57), QKeyCode "f11", number 0x57 +F11 0x57 + +# evdev 88 (0x58), QKeyCode "f12", number 0x58 +F12 0x58 + +# evdev 89 (0x59), QKeyCode "ro", number 0x73 + +# evdev 90 (0x5a): no evdev -> QKeyCode mapping (xkb keysym Katakana) + +# evdev 91 (0x5b), QKeyCode "hiragana", number 0x77 +Hiragana 0x77 + +# evdev 92 (0x5c), QKeyCode "henkan", number 0x79 +Henkan_Mode 0x79 + +# evdev 93 (0x5d), QKeyCode "katakanahiragana", number 0x70 +Hiragana_Katakana 0x70 + +# evdev 94 (0x5e), QKeyCode "muhenkan", number 0x7b +Muhenkan 0x7b + +# evdev 95 (0x5f): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 96 (0x60), QKeyCode "kp_enter", number 0x9c +KP_Enter 0x9c + +# evdev 97 (0x61), QKeyCode "ctrl_r", number 0x9d +Control_R 0x9d + +# evdev 98 (0x62), QKeyCode "kp_divide", number 0xb5 +KP_Divide 0xb5 + +# evdev 99 (0x63), QKeyCode "sysrq", number 0x54 +Print 0x54 + +# evdev 100 (0x64), QKeyCode "alt_r", number 0xb8 +Alt_R 0xb8 +Meta_R 0xb8 shift + +# evdev 101 (0x65), QKeyCode "lf", number 0x5b +Linefeed 0x5b + +# evdev 102 (0x66), QKeyCode "home", number 0xc7 +Home 0xc7 + +# evdev 103 (0x67), QKeyCode "up", number 0xc8 +Up 0xc8 + +# evdev 104 (0x68), QKeyCode "pgup", number 0xc9 +Prior 0xc9 + +# evdev 105 (0x69), QKeyCode "left", number 0xcb +Left 0xcb + +# evdev 106 (0x6a), QKeyCode "right", number 0xcd +Right 0xcd + +# evdev 107 (0x6b), QKeyCode "end", number 0xcf +End 0xcf + +# evdev 108 (0x6c), QKeyCode "down", number 0xd0 +Down 0xd0 + +# evdev 109 (0x6d), QKeyCode "pgdn", number 0xd1 +Next 0xd1 + +# evdev 110 (0x6e), QKeyCode "insert", number 0xd2 +Insert 0xd2 + +# evdev 111 (0x6f), QKeyCode "delete", number 0xd3 +Delete 0xd3 + +# evdev 112 (0x70): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 113 (0x71), QKeyCode "audiomute", number 0xa0 +XF86AudioMute 0xa0 + +# evdev 114 (0x72), QKeyCode "volumedown", number 0xae +XF86AudioLowerVolume 0xae + +# evdev 115 (0x73), QKeyCode "volumeup", number 0xb0 +XF86AudioRaiseVolume 0xb0 + +# evdev 116 (0x74), QKeyCode "power", number 0xde +XF86PowerOff 0xde + +# evdev 117 (0x75), QKeyCode "kp_equals", number 0x59 +KP_Equal 0x59 + +# evdev 118 (0x76): no evdev -> QKeyCode mapping (xkb keysym plusminus) + +# evdev 119 (0x77), QKeyCode "pause", number 0xc6 +Pause 0xc6 + +# evdev 120 (0x78): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchA) + +# evdev 121 (0x79), QKeyCode "kp_comma", number 0x7e +KP_Decimal 0x7e + +# evdev 122 (0x7a): no evdev -> QKeyCode mapping (xkb keysym Hangul) + +# evdev 123 (0x7b): no evdev -> QKeyCode mapping (xkb keysym Hangul_Hanja) + +# evdev 124 (0x7c), QKeyCode "yen", number 0x7d + +# evdev 125 (0x7d), QKeyCode "meta_l", number 0xdb +Super_L 0xdb + +# evdev 126 (0x7e), QKeyCode "meta_r", number 0xdc +Super_R 0xdc + +# evdev 127 (0x7f), QKeyCode "compose", number 0xdd +Menu 0xdd + +# evdev 128 (0x80), QKeyCode "stop", number 0xe8 +Cancel 0xe8 + +# evdev 129 (0x81), QKeyCode "again", number 0x85 +Redo 0x85 + +# evdev 130 (0x82), QKeyCode "props", number 0x86 +SunProps 0x86 + +# evdev 131 (0x83), QKeyCode "undo", number 0x87 +Undo 0x87 + +# evdev 132 (0x84), QKeyCode "front", number 0x8c +SunFront 0x8c + +# evdev 133 (0x85), QKeyCode "copy", number 0xf8 +XF86Copy 0xf8 + +# evdev 134 (0x86), QKeyCode "open", number 0x64 +XF86Open 0x64 + +# evdev 135 (0x87), QKeyCode "paste", number 0x65 +XF86Paste 0x65 + +# evdev 136 (0x88), QKeyCode "find", number 0xc1 +Find 0xc1 + +# evdev 137 (0x89), QKeyCode "cut", number 0xbc +XF86Cut 0xbc + +# evdev 138 (0x8a), QKeyCode "help", number 0xf5 +Help 0xf5 + +# evdev 139 (0x8b), QKeyCode "menu", number 0x9e +XF86MenuKB 0x9e + +# evdev 140 (0x8c), QKeyCode "calculator", number 0xa1 +XF86Calculator 0xa1 + +# evdev 141 (0x8d): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 142 (0x8e), QKeyCode "sleep", number 0xdf +XF86Sleep 0xdf + +# evdev 143 (0x8f), QKeyCode "wake", number 0xe3 +XF86WakeUp 0xe3 + +# evdev 144 (0x90): no evdev -> QKeyCode mapping (xkb keysym XF86Explorer) + +# evdev 145 (0x91): no evdev -> QKeyCode mapping (xkb keysym XF86Send) + +# evdev 146 (0x92): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 147 (0x93): no evdev -> QKeyCode mapping (xkb keysym XF86Xfer) + +# evdev 148 (0x94): no evdev -> QKeyCode mapping (xkb keysym XF86Launch1) + +# evdev 149 (0x95): no evdev -> QKeyCode mapping (xkb keysym XF86Launch2) + +# evdev 150 (0x96): no evdev -> QKeyCode mapping (xkb keysym XF86WWW) + +# evdev 151 (0x97): no evdev -> QKeyCode mapping (xkb keysym XF86DOS) + +# evdev 152 (0x98): no evdev -> QKeyCode mapping (xkb keysym XF86ScreenSaver) + +# evdev 153 (0x99): no evdev -> QKeyCode mapping (xkb keysym XF86RotateWindows) + +# evdev 154 (0x9a): no evdev -> QKeyCode mapping (xkb keysym XF86TaskPane) + +# evdev 155 (0x9b), QKeyCode "mail", number 0xec +XF86Mail 0xec + +# evdev 156 (0x9c), QKeyCode "ac_bookmarks", number 0xe6 +XF86Favorites 0xe6 + +# evdev 157 (0x9d), QKeyCode "computer", number 0xeb +XF86MyComputer 0xeb + +# evdev 158 (0x9e), QKeyCode "ac_back", number 0xea +XF86Back 0xea + +# evdev 159 (0x9f), QKeyCode "ac_forward", number 0xe9 +XF86Forward 0xe9 + +# evdev 160 (0xa0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 161 (0xa1): no evdev -> QKeyCode mapping (xkb keysym XF86Eject) + +# evdev 162 (0xa2): no evdev -> QKeyCode mapping (xkb keysym XF86Eject) + +# evdev 163 (0xa3), QKeyCode "audionext", number 0x99 +XF86AudioNext 0x99 + +# evdev 164 (0xa4), QKeyCode "audioplay", number 0xa2 +XF86AudioPlay 0xa2 +XF86AudioPause 0xa2 shift + +# evdev 165 (0xa5), QKeyCode "audioprev", number 0x90 +XF86AudioPrev 0x90 + +# evdev 166 (0xa6), QKeyCode "audiostop", number 0xa4 +XF86AudioStop 0xa4 +XF86Eject 0xa4 shift + +# evdev 167 (0xa7): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRecord) + +# evdev 168 (0xa8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRewind) + +# evdev 169 (0xa9): no evdev -> QKeyCode mapping (xkb keysym XF86Phone) + +# evdev 170 (0xaa): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 171 (0xab): no evdev -> QKeyCode mapping (xkb keysym XF86Tools) + +# evdev 172 (0xac), QKeyCode "ac_home", number 0xb2 +XF86HomePage 0xb2 + +# evdev 173 (0xad), QKeyCode "ac_refresh", number 0xe7 +XF86Reload 0xe7 + +# evdev 174 (0xae): no evdev -> QKeyCode mapping (xkb keysym XF86Close) + +# evdev 175 (0xaf): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 176 (0xb0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 177 (0xb1): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollUp) + +# evdev 178 (0xb2): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollDown) + +# evdev 179 (0xb3): no evdev -> QKeyCode mapping (xkb keysym parenleft) + +# evdev 180 (0xb4): no evdev -> QKeyCode mapping (xkb keysym parenright) + +# evdev 181 (0xb5): no evdev -> QKeyCode mapping (xkb keysym XF86New) + +# evdev 182 (0xb6): no evdev -> QKeyCode mapping (xkb keysym Redo) + +# evdev 183 (0xb7): no evdev -> QKeyCode mapping (xkb keysym XF86Tools) + +# evdev 184 (0xb8): no evdev -> QKeyCode mapping (xkb keysym XF86Launch5) + +# evdev 185 (0xb9): no evdev -> QKeyCode mapping (xkb keysym XF86Launch6) + +# evdev 186 (0xba): no evdev -> QKeyCode mapping (xkb keysym XF86Launch7) + +# evdev 187 (0xbb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch8) + +# evdev 188 (0xbc): no evdev -> QKeyCode mapping (xkb keysym XF86Launch9) + +# evdev 189 (0xbd): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 190 (0xbe): no evdev -> QKeyCode mapping (xkb keysym XF86AudioMicMute) + +# evdev 191 (0xbf): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadToggle) + +# evdev 192 (0xc0): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOn) + +# evdev 193 (0xc1): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOff) + +# evdev 194 (0xc2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 195 (0xc3): no evdev -> QKeyCode mapping (xkb keysym Mode_switch) + +# evdev 196 (0xc4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 197 (0xc5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 198 (0xc6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 199 (0xc7): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 200 (0xc8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay) + +# evdev 201 (0xc9): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPause) + +# evdev 202 (0xca): no evdev -> QKeyCode mapping (xkb keysym XF86Launch3) + +# evdev 203 (0xcb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch4) + +# evdev 204 (0xcc): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchB) + +# evdev 205 (0xcd): no evdev -> QKeyCode mapping (xkb keysym XF86Suspend) + +# evdev 206 (0xce): no evdev -> QKeyCode mapping (xkb keysym XF86Close) + +# evdev 207 (0xcf): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay) + +# evdev 208 (0xd0): no evdev -> QKeyCode mapping (xkb keysym XF86AudioForward) + +# evdev 209 (0xd1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 210 (0xd2): no evdev -> QKeyCode mapping (xkb keysym Print) + +# evdev 211 (0xd3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 212 (0xd4): no evdev -> QKeyCode mapping (xkb keysym XF86WebCam) + +# evdev 213 (0xd5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 214 (0xd6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 215 (0xd7): no evdev -> QKeyCode mapping (xkb keysym XF86Mail) + +# evdev 216 (0xd8): no evdev -> QKeyCode mapping (xkb keysym XF86Messenger) + +# evdev 217 (0xd9): no evdev -> QKeyCode mapping (xkb keysym XF86Search) + +# evdev 218 (0xda): no evdev -> QKeyCode mapping (xkb keysym XF86Go) + +# evdev 219 (0xdb): no evdev -> QKeyCode mapping (xkb keysym XF86Finance) + +# evdev 220 (0xdc): no evdev -> QKeyCode mapping (xkb keysym XF86Game) + +# evdev 221 (0xdd): no evdev -> QKeyCode mapping (xkb keysym XF86Shop) + +# evdev 222 (0xde): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 223 (0xdf): no evdev -> QKeyCode mapping (xkb keysym Cancel) + +# evdev 224 (0xe0): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessDown) + +# evdev 225 (0xe1): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessUp) + +# evdev 226 (0xe2), QKeyCode "mediaselect", number 0xed +XF86AudioMedia 0xed + +# evdev 227 (0xe3): no evdev -> QKeyCode mapping (xkb keysym XF86Display) + +# evdev 228 (0xe4): no evdev -> QKeyCode mapping (xkb keysym XF86KbdLightOnOff) + +# evdev 229 (0xe5): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessDown) + +# evdev 230 (0xe6): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessUp) + +# evdev 231 (0xe7): no evdev -> QKeyCode mapping (xkb keysym XF86Send) + +# evdev 232 (0xe8): no evdev -> QKeyCode mapping (xkb keysym XF86Reply) + +# evdev 233 (0xe9): no evdev -> QKeyCode mapping (xkb keysym XF86MailForward) + +# evdev 234 (0xea): no evdev -> QKeyCode mapping (xkb keysym XF86Save) + +# evdev 235 (0xeb): no evdev -> QKeyCode mapping (xkb keysym XF86Documents) + +# evdev 236 (0xec): no evdev -> QKeyCode mapping (xkb keysym XF86Battery) + +# evdev 237 (0xed): no evdev -> QKeyCode mapping (xkb keysym XF86Bluetooth) + +# evdev 238 (0xee): no evdev -> QKeyCode mapping (xkb keysym XF86WLAN) + +# evdev 239 (0xef): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 240 (0xf0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 241 (0xf1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 242 (0xf2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 243 (0xf3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 244 (0xf4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 245 (0xf5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 246 (0xf6): no evdev -> QKeyCode mapping (xkb keysym Invalid) + +# evdev 247 (0xf7): no evdev -> QKeyCode mapping (xkb keysym Invalid) + +# +# quirks section start +# +# Sometimes multiple keysyms map to the same keycodes. +# The keycode -> keysym lookup finds only one of the +# keysyms. So append them here. +# + +Print 0x54 +Sys_Req 0x54 +Execute 0x54 +KP_Decimal 0x53 numlock +KP_Separator 0x53 numlock +Alt_R 0xb8 +ISO_Level3_Shift 0xb8 +Mode_switch 0xb8 + +# quirks section end diff --git a/app/src/main/assets/roms/keymaps/tr b/app/src/main/assets/roms/keymaps/tr new file mode 100644 index 0000000..8ef60a6 --- /dev/null +++ b/app/src/main/assets/roms/keymaps/tr @@ -0,0 +1,836 @@ +# +# generated by qemu-keymap +# model : pc105 +# layout : tr +# variant : - +# options : - + +# name: "Turkish" + +# modifiers +# 0: Shift +# 1: Lock +# 2: Control +# 3: Mod1 +# 4: Mod2 +# 5: Mod3 +# 6: Mod4 +# 7: Mod5 +# 8: NumLock +# 9: Alt +# 10: LevelThree +# 11: LAlt +# 12: RAlt +# 13: RControl +# 14: LControl +# 15: ScrollLock +# 16: LevelFive +# 17: AltGr +# 18: Meta +# 19: Super +# 20: Hyper + +# evdev 1 (0x1), QKeyCode "esc", number 0x1 +Escape 0x01 + +# evdev 2 (0x2), QKeyCode "1", number 0x2 +1 0x02 +exclam 0x02 shift +greater 0x02 altgr +exclamdown 0x02 shift altgr + +# evdev 3 (0x3), QKeyCode "2", number 0x3 +2 0x03 +apostrophe 0x03 shift +sterling 0x03 altgr +twosuperior 0x03 shift altgr + +# evdev 4 (0x4), QKeyCode "3", number 0x4 +3 0x04 +asciicircum 0x04 shift +numbersign 0x04 altgr +threesuperior 0x04 shift altgr + +# evdev 5 (0x5), QKeyCode "4", number 0x5 +4 0x05 +plus 0x05 shift +dollar 0x05 altgr +onequarter 0x05 shift altgr + +# evdev 6 (0x6), QKeyCode "5", number 0x6 +5 0x06 +percent 0x06 shift +onehalf 0x06 altgr +threeeighths 0x06 shift altgr + +# evdev 7 (0x7), QKeyCode "6", number 0x7 +6 0x07 +ampersand 0x07 shift +threequarters 0x07 altgr +VoidSymbol 0x07 shift altgr + +# evdev 8 (0x8), QKeyCode "7", number 0x8 +7 0x08 +slash 0x08 shift +braceleft 0x08 altgr +VoidSymbol 0x08 shift altgr + +# evdev 9 (0x9), QKeyCode "8", number 0x9 +8 0x09 +parenleft 0x09 shift +bracketleft 0x09 altgr +VoidSymbol 0x09 shift altgr + +# evdev 10 (0xa), QKeyCode "9", number 0xa +9 0x0a +parenright 0x0a shift +bracketright 0x0a altgr +plusminus 0x0a shift altgr + +# evdev 11 (0xb), QKeyCode "0", number 0xb +0 0x0b +equal 0x0b shift +braceright 0x0b altgr +degree 0x0b shift altgr + +# evdev 12 (0xc), QKeyCode "minus", number 0xc +asterisk 0x0c +question 0x0c shift +backslash 0x0c altgr +questiondown 0x0c shift altgr + +# evdev 13 (0xd), QKeyCode "equal", number 0xd +minus 0x0d +underscore 0x0d shift +bar 0x0d altgr +VoidSymbol 0x0d shift altgr + +# evdev 14 (0xe), QKeyCode "backspace", number 0xe +BackSpace 0x0e + +# evdev 15 (0xf), QKeyCode "tab", number 0xf +Tab 0x0f +ISO_Left_Tab 0x0f shift + +# evdev 16 (0x10), QKeyCode "q", number 0x10 +q 0x10 +Q 0x10 shift +at 0x10 altgr +Greek_OMEGA 0x10 shift altgr + +# evdev 17 (0x11), QKeyCode "w", number 0x11 +w 0x11 +W 0x11 shift +VoidSymbol 0x11 altgr + +# evdev 18 (0x12), QKeyCode "e", number 0x12 +e 0x12 +E 0x12 shift +EuroSign 0x12 altgr +VoidSymbol 0x12 shift altgr + +# evdev 19 (0x13), QKeyCode "r", number 0x13 +r 0x13 +R 0x13 shift +paragraph 0x13 altgr +registered 0x13 shift altgr + +# evdev 20 (0x14), QKeyCode "t", number 0x14 +t 0x14 +T 0x14 shift +U20BA 0x14 altgr +VoidSymbol 0x14 shift altgr + +# evdev 21 (0x15), QKeyCode "y", number 0x15 +y 0x15 +Y 0x15 shift +leftarrow 0x15 altgr +yen 0x15 shift altgr + +# evdev 22 (0x16), QKeyCode "u", number 0x16 +u 0x16 +U 0x16 shift +ucircumflex 0x16 altgr +Ucircumflex 0x16 shift altgr + +# evdev 23 (0x17), QKeyCode "i", number 0x17 +idotless 0x17 +I 0x17 shift +icircumflex 0x17 altgr +Icircumflex 0x17 shift altgr + +# evdev 24 (0x18), QKeyCode "o", number 0x18 +o 0x18 +O 0x18 shift +ocircumflex 0x18 altgr +Ocircumflex 0x18 shift altgr + +# evdev 25 (0x19), QKeyCode "p", number 0x19 +p 0x19 +P 0x19 shift +VoidSymbol 0x19 altgr + +# evdev 26 (0x1a), QKeyCode "bracket_left", number 0x1a +gbreve 0x1a +Gbreve 0x1a shift +dead_diaeresis 0x1a altgr +dead_abovering 0x1a shift altgr + +# evdev 27 (0x1b), QKeyCode "bracket_right", number 0x1b +udiaeresis 0x1b +Udiaeresis 0x1b shift +asciitilde 0x1b altgr +dead_macron 0x1b shift altgr + +# evdev 28 (0x1c), QKeyCode "ret", number 0x1c +Return 0x1c + +# evdev 29 (0x1d), QKeyCode "ctrl", number 0x1d +Control_L 0x1d + +# evdev 30 (0x1e), QKeyCode "a", number 0x1e +a 0x1e +A 0x1e shift +acircumflex 0x1e altgr +Acircumflex 0x1e shift altgr + +# evdev 31 (0x1f), QKeyCode "s", number 0x1f +s 0x1f +S 0x1f shift +section 0x1f altgr +VoidSymbol 0x1f shift altgr + +# evdev 32 (0x20), QKeyCode "d", number 0x20 +d 0x20 +D 0x20 shift +VoidSymbol 0x20 altgr + +# evdev 33 (0x21), QKeyCode "f", number 0x21 +f 0x21 +F 0x21 shift +ordfeminine 0x21 altgr +VoidSymbol 0x21 shift altgr + +# evdev 34 (0x22), QKeyCode "g", number 0x22 +g 0x22 +G 0x22 shift +VoidSymbol 0x22 altgr + +# evdev 35 (0x23), QKeyCode "h", number 0x23 +h 0x23 +H 0x23 shift +VoidSymbol 0x23 altgr + +# evdev 36 (0x24), QKeyCode "j", number 0x24 +j 0x24 +J 0x24 shift +dead_hook 0x24 altgr +dead_horn 0x24 shift altgr + +# evdev 37 (0x25), QKeyCode "k", number 0x25 +k 0x25 +K 0x25 shift +VoidSymbol 0x25 altgr + +# evdev 38 (0x26), QKeyCode "l", number 0x26 +l 0x26 +L 0x26 shift +VoidSymbol 0x26 altgr + +# evdev 39 (0x27), QKeyCode "semicolon", number 0x27 +scedilla 0x27 +Scedilla 0x27 shift +acute 0x27 altgr +dead_acute 0x27 shift altgr + +# evdev 40 (0x28), QKeyCode "apostrophe", number 0x28 +i 0x28 +Iabovedot 0x28 shift +apostrophe 0x28 altgr +dead_caron 0x28 shift altgr + +# evdev 41 (0x29), QKeyCode "grave_accent", number 0x29 +quotedbl 0x29 +eacute 0x29 shift +less 0x29 altgr +degree 0x29 shift altgr + +# evdev 42 (0x2a), QKeyCode "shift", number 0x2a +Shift_L 0x2a + +# evdev 43 (0x2b), QKeyCode "backslash", number 0x2b +comma 0x2b +semicolon 0x2b shift +grave 0x2b altgr +dead_grave 0x2b shift altgr + +# evdev 44 (0x2c), QKeyCode "z", number 0x2c +z 0x2c +Z 0x2c shift +guillemotleft 0x2c altgr +less 0x2c shift altgr + +# evdev 45 (0x2d), QKeyCode "x", number 0x2d +x 0x2d +X 0x2d shift +guillemotright 0x2d altgr +greater 0x2d shift altgr + +# evdev 46 (0x2e), QKeyCode "c", number 0x2e +c 0x2e +C 0x2e shift +cent 0x2e altgr +copyright 0x2e shift altgr + +# evdev 47 (0x2f), QKeyCode "v", number 0x2f +v 0x2f +V 0x2f shift +leftdoublequotemark 0x2f altgr +leftsinglequotemark 0x2f shift altgr + +# evdev 48 (0x30), QKeyCode "b", number 0x30 +b 0x30 +B 0x30 shift +rightdoublequotemark 0x30 altgr +rightsinglequotemark 0x30 shift altgr + +# evdev 49 (0x31), QKeyCode "n", number 0x31 +n 0x31 +N 0x31 shift + +# evdev 50 (0x32), QKeyCode "m", number 0x32 +m 0x32 +M 0x32 shift +mu 0x32 altgr +masculine 0x32 shift altgr + +# evdev 51 (0x33), QKeyCode "comma", number 0x33 +odiaeresis 0x33 +Odiaeresis 0x33 shift +multiply 0x33 altgr +VoidSymbol 0x33 shift altgr + +# evdev 52 (0x34), QKeyCode "dot", number 0x34 +ccedilla 0x34 +Ccedilla 0x34 shift +periodcentered 0x34 altgr +division 0x34 shift altgr + +# evdev 53 (0x35), QKeyCode "slash", number 0x35 +period 0x35 +colon 0x35 shift +dead_abovedot 0x35 altgr + +# evdev 54 (0x36), QKeyCode "shift_r", number 0x36 +Shift_R 0x36 + +# evdev 55 (0x37), QKeyCode "kp_multiply", number 0x37 +KP_Multiply 0x37 + +# evdev 56 (0x38), QKeyCode "alt", number 0x38 +Alt_L 0x38 +Meta_L 0x38 shift + +# evdev 57 (0x39), QKeyCode "spc", number 0x39 +space 0x39 + +# evdev 58 (0x3a), QKeyCode "caps_lock", number 0x3a +Caps_Lock 0x3a + +# evdev 59 (0x3b), QKeyCode "f1", number 0x3b +F1 0x3b + +# evdev 60 (0x3c), QKeyCode "f2", number 0x3c +F2 0x3c + +# evdev 61 (0x3d), QKeyCode "f3", number 0x3d +F3 0x3d + +# evdev 62 (0x3e), QKeyCode "f4", number 0x3e +F4 0x3e + +# evdev 63 (0x3f), QKeyCode "f5", number 0x3f +F5 0x3f + +# evdev 64 (0x40), QKeyCode "f6", number 0x40 +F6 0x40 + +# evdev 65 (0x41), QKeyCode "f7", number 0x41 +F7 0x41 + +# evdev 66 (0x42), QKeyCode "f8", number 0x42 +F8 0x42 + +# evdev 67 (0x43), QKeyCode "f9", number 0x43 +F9 0x43 + +# evdev 68 (0x44), QKeyCode "f10", number 0x44 +F10 0x44 + +# evdev 69 (0x45), QKeyCode "num_lock", number 0x45 +Num_Lock 0x45 + +# evdev 70 (0x46), QKeyCode "scroll_lock", number 0x46 +Scroll_Lock 0x46 + +# evdev 71 (0x47), QKeyCode "kp_7", number 0x47 +KP_Home 0x47 +KP_7 0x47 numlock + +# evdev 72 (0x48), QKeyCode "kp_8", number 0x48 +KP_Up 0x48 +KP_8 0x48 numlock + +# evdev 73 (0x49), QKeyCode "kp_9", number 0x49 +KP_Prior 0x49 +KP_9 0x49 numlock + +# evdev 74 (0x4a), QKeyCode "kp_subtract", number 0x4a +KP_Subtract 0x4a + +# evdev 75 (0x4b), QKeyCode "kp_4", number 0x4b +KP_Left 0x4b +KP_4 0x4b numlock + +# evdev 76 (0x4c), QKeyCode "kp_5", number 0x4c +KP_Begin 0x4c +KP_5 0x4c numlock + +# evdev 77 (0x4d), QKeyCode "kp_6", number 0x4d +KP_Right 0x4d +KP_6 0x4d numlock + +# evdev 78 (0x4e), QKeyCode "kp_add", number 0x4e +KP_Add 0x4e + +# evdev 79 (0x4f), QKeyCode "kp_1", number 0x4f +KP_End 0x4f +KP_1 0x4f numlock + +# evdev 80 (0x50), QKeyCode "kp_2", number 0x50 +KP_Down 0x50 +KP_2 0x50 numlock + +# evdev 81 (0x51), QKeyCode "kp_3", number 0x51 +KP_Next 0x51 +KP_3 0x51 numlock + +# evdev 82 (0x52), QKeyCode "kp_0", number 0x52 +KP_Insert 0x52 +KP_0 0x52 numlock + +# evdev 83 (0x53), QKeyCode "kp_decimal", number 0x53 +KP_Delete 0x53 +KP_Separator 0x53 numlock + +# evdev 84 (0x54): no evdev -> QKeyCode mapping (xkb keysym ISO_Level3_Shift) + +# evdev 85 (0x55): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 86 (0x56), QKeyCode "less", number 0x56 +less 0x56 +greater 0x56 shift +bar 0x56 altgr +brokenbar 0x56 shift altgr + +# evdev 87 (0x57), QKeyCode "f11", number 0x57 +F11 0x57 + +# evdev 88 (0x58), QKeyCode "f12", number 0x58 +F12 0x58 + +# evdev 89 (0x59), QKeyCode "ro", number 0x73 + +# evdev 90 (0x5a): no evdev -> QKeyCode mapping (xkb keysym Katakana) + +# evdev 91 (0x5b), QKeyCode "hiragana", number 0x77 +Hiragana 0x77 + +# evdev 92 (0x5c), QKeyCode "henkan", number 0x79 +Henkan_Mode 0x79 + +# evdev 93 (0x5d), QKeyCode "katakanahiragana", number 0x70 +Hiragana_Katakana 0x70 + +# evdev 94 (0x5e), QKeyCode "muhenkan", number 0x7b +Muhenkan 0x7b + +# evdev 95 (0x5f): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 96 (0x60), QKeyCode "kp_enter", number 0x9c +KP_Enter 0x9c + +# evdev 97 (0x61), QKeyCode "ctrl_r", number 0x9d +Control_R 0x9d + +# evdev 98 (0x62), QKeyCode "kp_divide", number 0xb5 +KP_Divide 0xb5 + +# evdev 99 (0x63), QKeyCode "sysrq", number 0x54 +Print 0x54 + +# evdev 100 (0x64), QKeyCode "alt_r", number 0xb8 +ISO_Level3_Shift 0xb8 + +# evdev 101 (0x65), QKeyCode "lf", number 0x5b +Linefeed 0x5b + +# evdev 102 (0x66), QKeyCode "home", number 0xc7 +Home 0xc7 + +# evdev 103 (0x67), QKeyCode "up", number 0xc8 +Up 0xc8 + +# evdev 104 (0x68), QKeyCode "pgup", number 0xc9 +Prior 0xc9 + +# evdev 105 (0x69), QKeyCode "left", number 0xcb +Left 0xcb + +# evdev 106 (0x6a), QKeyCode "right", number 0xcd +Right 0xcd + +# evdev 107 (0x6b), QKeyCode "end", number 0xcf +End 0xcf + +# evdev 108 (0x6c), QKeyCode "down", number 0xd0 +Down 0xd0 + +# evdev 109 (0x6d), QKeyCode "pgdn", number 0xd1 +Next 0xd1 + +# evdev 110 (0x6e), QKeyCode "insert", number 0xd2 +Insert 0xd2 + +# evdev 111 (0x6f), QKeyCode "delete", number 0xd3 +Delete 0xd3 + +# evdev 112 (0x70): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 113 (0x71), QKeyCode "audiomute", number 0xa0 +XF86AudioMute 0xa0 + +# evdev 114 (0x72), QKeyCode "volumedown", number 0xae +XF86AudioLowerVolume 0xae + +# evdev 115 (0x73), QKeyCode "volumeup", number 0xb0 +XF86AudioRaiseVolume 0xb0 + +# evdev 116 (0x74), QKeyCode "power", number 0xde +XF86PowerOff 0xde + +# evdev 117 (0x75), QKeyCode "kp_equals", number 0x59 +KP_Equal 0x59 + +# evdev 118 (0x76): no evdev -> QKeyCode mapping (xkb keysym plusminus) + +# evdev 119 (0x77), QKeyCode "pause", number 0xc6 +Pause 0xc6 + +# evdev 120 (0x78): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchA) + +# evdev 121 (0x79), QKeyCode "kp_comma", number 0x7e +KP_Decimal 0x7e + +# evdev 122 (0x7a): no evdev -> QKeyCode mapping (xkb keysym Hangul) + +# evdev 123 (0x7b): no evdev -> QKeyCode mapping (xkb keysym Hangul_Hanja) + +# evdev 124 (0x7c), QKeyCode "yen", number 0x7d + +# evdev 125 (0x7d), QKeyCode "meta_l", number 0xdb +Super_L 0xdb + +# evdev 126 (0x7e), QKeyCode "meta_r", number 0xdc +Super_R 0xdc + +# evdev 127 (0x7f), QKeyCode "compose", number 0xdd +Menu 0xdd + +# evdev 128 (0x80), QKeyCode "stop", number 0xe8 +Cancel 0xe8 + +# evdev 129 (0x81), QKeyCode "again", number 0x85 +Redo 0x85 + +# evdev 130 (0x82), QKeyCode "props", number 0x86 +SunProps 0x86 + +# evdev 131 (0x83), QKeyCode "undo", number 0x87 +Undo 0x87 + +# evdev 132 (0x84), QKeyCode "front", number 0x8c +SunFront 0x8c + +# evdev 133 (0x85), QKeyCode "copy", number 0xf8 +XF86Copy 0xf8 + +# evdev 134 (0x86), QKeyCode "open", number 0x64 +XF86Open 0x64 + +# evdev 135 (0x87), QKeyCode "paste", number 0x65 +XF86Paste 0x65 + +# evdev 136 (0x88), QKeyCode "find", number 0xc1 +Find 0xc1 + +# evdev 137 (0x89), QKeyCode "cut", number 0xbc +XF86Cut 0xbc + +# evdev 138 (0x8a), QKeyCode "help", number 0xf5 +Help 0xf5 + +# evdev 139 (0x8b), QKeyCode "menu", number 0x9e +XF86MenuKB 0x9e + +# evdev 140 (0x8c), QKeyCode "calculator", number 0xa1 +XF86Calculator 0xa1 + +# evdev 141 (0x8d): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 142 (0x8e), QKeyCode "sleep", number 0xdf +XF86Sleep 0xdf + +# evdev 143 (0x8f), QKeyCode "wake", number 0xe3 +XF86WakeUp 0xe3 + +# evdev 144 (0x90): no evdev -> QKeyCode mapping (xkb keysym XF86Explorer) + +# evdev 145 (0x91): no evdev -> QKeyCode mapping (xkb keysym XF86Send) + +# evdev 146 (0x92): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 147 (0x93): no evdev -> QKeyCode mapping (xkb keysym XF86Xfer) + +# evdev 148 (0x94): no evdev -> QKeyCode mapping (xkb keysym XF86Launch1) + +# evdev 149 (0x95): no evdev -> QKeyCode mapping (xkb keysym XF86Launch2) + +# evdev 150 (0x96): no evdev -> QKeyCode mapping (xkb keysym XF86WWW) + +# evdev 151 (0x97): no evdev -> QKeyCode mapping (xkb keysym XF86DOS) + +# evdev 152 (0x98): no evdev -> QKeyCode mapping (xkb keysym XF86ScreenSaver) + +# evdev 153 (0x99): no evdev -> QKeyCode mapping (xkb keysym XF86RotateWindows) + +# evdev 154 (0x9a): no evdev -> QKeyCode mapping (xkb keysym XF86TaskPane) + +# evdev 155 (0x9b), QKeyCode "mail", number 0xec +XF86Mail 0xec + +# evdev 156 (0x9c), QKeyCode "ac_bookmarks", number 0xe6 +XF86Favorites 0xe6 + +# evdev 157 (0x9d), QKeyCode "computer", number 0xeb +XF86MyComputer 0xeb + +# evdev 158 (0x9e), QKeyCode "ac_back", number 0xea +XF86Back 0xea + +# evdev 159 (0x9f), QKeyCode "ac_forward", number 0xe9 +XF86Forward 0xe9 + +# evdev 160 (0xa0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 161 (0xa1): no evdev -> QKeyCode mapping (xkb keysym XF86Eject) + +# evdev 162 (0xa2): no evdev -> QKeyCode mapping (xkb keysym XF86Eject) + +# evdev 163 (0xa3), QKeyCode "audionext", number 0x99 +XF86AudioNext 0x99 + +# evdev 164 (0xa4), QKeyCode "audioplay", number 0xa2 +XF86AudioPlay 0xa2 +XF86AudioPause 0xa2 shift + +# evdev 165 (0xa5), QKeyCode "audioprev", number 0x90 +XF86AudioPrev 0x90 + +# evdev 166 (0xa6), QKeyCode "audiostop", number 0xa4 +XF86AudioStop 0xa4 +XF86Eject 0xa4 shift + +# evdev 167 (0xa7): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRecord) + +# evdev 168 (0xa8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRewind) + +# evdev 169 (0xa9): no evdev -> QKeyCode mapping (xkb keysym XF86Phone) + +# evdev 170 (0xaa): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 171 (0xab): no evdev -> QKeyCode mapping (xkb keysym XF86Tools) + +# evdev 172 (0xac), QKeyCode "ac_home", number 0xb2 +XF86HomePage 0xb2 + +# evdev 173 (0xad), QKeyCode "ac_refresh", number 0xe7 +XF86Reload 0xe7 + +# evdev 174 (0xae): no evdev -> QKeyCode mapping (xkb keysym XF86Close) + +# evdev 175 (0xaf): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 176 (0xb0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 177 (0xb1): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollUp) + +# evdev 178 (0xb2): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollDown) + +# evdev 179 (0xb3): no evdev -> QKeyCode mapping (xkb keysym parenleft) + +# evdev 180 (0xb4): no evdev -> QKeyCode mapping (xkb keysym parenright) + +# evdev 181 (0xb5): no evdev -> QKeyCode mapping (xkb keysym XF86New) + +# evdev 182 (0xb6): no evdev -> QKeyCode mapping (xkb keysym Redo) + +# evdev 183 (0xb7): no evdev -> QKeyCode mapping (xkb keysym XF86Tools) + +# evdev 184 (0xb8): no evdev -> QKeyCode mapping (xkb keysym XF86Launch5) + +# evdev 185 (0xb9): no evdev -> QKeyCode mapping (xkb keysym XF86Launch6) + +# evdev 186 (0xba): no evdev -> QKeyCode mapping (xkb keysym XF86Launch7) + +# evdev 187 (0xbb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch8) + +# evdev 188 (0xbc): no evdev -> QKeyCode mapping (xkb keysym XF86Launch9) + +# evdev 189 (0xbd): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 190 (0xbe): no evdev -> QKeyCode mapping (xkb keysym XF86AudioMicMute) + +# evdev 191 (0xbf): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadToggle) + +# evdev 192 (0xc0): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOn) + +# evdev 193 (0xc1): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOff) + +# evdev 194 (0xc2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 195 (0xc3): no evdev -> QKeyCode mapping (xkb keysym Mode_switch) + +# evdev 196 (0xc4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 197 (0xc5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 198 (0xc6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 199 (0xc7): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 200 (0xc8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay) + +# evdev 201 (0xc9): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPause) + +# evdev 202 (0xca): no evdev -> QKeyCode mapping (xkb keysym XF86Launch3) + +# evdev 203 (0xcb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch4) + +# evdev 204 (0xcc): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchB) + +# evdev 205 (0xcd): no evdev -> QKeyCode mapping (xkb keysym XF86Suspend) + +# evdev 206 (0xce): no evdev -> QKeyCode mapping (xkb keysym XF86Close) + +# evdev 207 (0xcf): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay) + +# evdev 208 (0xd0): no evdev -> QKeyCode mapping (xkb keysym XF86AudioForward) + +# evdev 209 (0xd1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 210 (0xd2): no evdev -> QKeyCode mapping (xkb keysym Print) + +# evdev 211 (0xd3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 212 (0xd4): no evdev -> QKeyCode mapping (xkb keysym XF86WebCam) + +# evdev 213 (0xd5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 214 (0xd6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 215 (0xd7): no evdev -> QKeyCode mapping (xkb keysym XF86Mail) + +# evdev 216 (0xd8): no evdev -> QKeyCode mapping (xkb keysym XF86Messenger) + +# evdev 217 (0xd9): no evdev -> QKeyCode mapping (xkb keysym XF86Search) + +# evdev 218 (0xda): no evdev -> QKeyCode mapping (xkb keysym XF86Go) + +# evdev 219 (0xdb): no evdev -> QKeyCode mapping (xkb keysym XF86Finance) + +# evdev 220 (0xdc): no evdev -> QKeyCode mapping (xkb keysym XF86Game) + +# evdev 221 (0xdd): no evdev -> QKeyCode mapping (xkb keysym XF86Shop) + +# evdev 222 (0xde): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 223 (0xdf): no evdev -> QKeyCode mapping (xkb keysym Cancel) + +# evdev 224 (0xe0): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessDown) + +# evdev 225 (0xe1): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessUp) + +# evdev 226 (0xe2), QKeyCode "mediaselect", number 0xed +XF86AudioMedia 0xed + +# evdev 227 (0xe3): no evdev -> QKeyCode mapping (xkb keysym XF86Display) + +# evdev 228 (0xe4): no evdev -> QKeyCode mapping (xkb keysym XF86KbdLightOnOff) + +# evdev 229 (0xe5): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessDown) + +# evdev 230 (0xe6): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessUp) + +# evdev 231 (0xe7): no evdev -> QKeyCode mapping (xkb keysym XF86Send) + +# evdev 232 (0xe8): no evdev -> QKeyCode mapping (xkb keysym XF86Reply) + +# evdev 233 (0xe9): no evdev -> QKeyCode mapping (xkb keysym XF86MailForward) + +# evdev 234 (0xea): no evdev -> QKeyCode mapping (xkb keysym XF86Save) + +# evdev 235 (0xeb): no evdev -> QKeyCode mapping (xkb keysym XF86Documents) + +# evdev 236 (0xec): no evdev -> QKeyCode mapping (xkb keysym XF86Battery) + +# evdev 237 (0xed): no evdev -> QKeyCode mapping (xkb keysym XF86Bluetooth) + +# evdev 238 (0xee): no evdev -> QKeyCode mapping (xkb keysym XF86WLAN) + +# evdev 239 (0xef): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 240 (0xf0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 241 (0xf1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 242 (0xf2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 243 (0xf3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 244 (0xf4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 245 (0xf5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol) + +# evdev 246 (0xf6): no evdev -> QKeyCode mapping (xkb keysym Invalid) + +# evdev 247 (0xf7): no evdev -> QKeyCode mapping (xkb keysym Invalid) + +# +# quirks section start +# +# Sometimes multiple keysyms map to the same keycodes. +# The keycode -> keysym lookup finds only one of the +# keysyms. So append them here. +# + +Print 0x54 +Sys_Req 0x54 +Execute 0x54 +KP_Decimal 0x53 numlock +KP_Separator 0x53 numlock +Alt_R 0xb8 +ISO_Level3_Shift 0xb8 +Mode_switch 0xb8 + +# quirks section end diff --git a/app/src/main/assets/roms/kvmvapic.bin b/app/src/main/assets/roms/kvmvapic.bin new file mode 100644 index 0000000..045f5c2 Binary files /dev/null and b/app/src/main/assets/roms/kvmvapic.bin differ diff --git a/app/src/main/assets/roms/linuxboot.bin b/app/src/main/assets/roms/linuxboot.bin new file mode 100644 index 0000000..923d179 Binary files /dev/null and b/app/src/main/assets/roms/linuxboot.bin differ diff --git a/app/src/main/assets/roms/linuxboot_dma.bin b/app/src/main/assets/roms/linuxboot_dma.bin new file mode 100644 index 0000000..d176f62 Binary files /dev/null and b/app/src/main/assets/roms/linuxboot_dma.bin differ diff --git a/app/src/main/assets/roms/multiboot.bin b/app/src/main/assets/roms/multiboot.bin new file mode 100644 index 0000000..e772713 Binary files /dev/null and b/app/src/main/assets/roms/multiboot.bin differ diff --git a/app/src/main/assets/roms/openbios-ppc b/app/src/main/assets/roms/openbios-ppc new file mode 100644 index 0000000..def6d4c Binary files /dev/null and b/app/src/main/assets/roms/openbios-ppc differ diff --git a/app/src/main/assets/roms/openbios-sparc32 b/app/src/main/assets/roms/openbios-sparc32 new file mode 100644 index 0000000..67b8b83 Binary files /dev/null and b/app/src/main/assets/roms/openbios-sparc32 differ diff --git a/app/src/main/assets/roms/openbios-sparc64 b/app/src/main/assets/roms/openbios-sparc64 new file mode 100644 index 0000000..dfa1f10 Binary files /dev/null and b/app/src/main/assets/roms/openbios-sparc64 differ diff --git a/app/src/main/assets/roms/opensbi-riscv32-sifive_u-fw_jump.bin b/app/src/main/assets/roms/opensbi-riscv32-sifive_u-fw_jump.bin new file mode 100644 index 0000000..3e0da54 Binary files /dev/null and b/app/src/main/assets/roms/opensbi-riscv32-sifive_u-fw_jump.bin differ diff --git a/app/src/main/assets/roms/opensbi-riscv32-virt-fw_jump.bin b/app/src/main/assets/roms/opensbi-riscv32-virt-fw_jump.bin new file mode 100644 index 0000000..bc56ed6 Binary files /dev/null and b/app/src/main/assets/roms/opensbi-riscv32-virt-fw_jump.bin differ diff --git a/app/src/main/assets/roms/opensbi-riscv64-sifive_u-fw_jump.bin b/app/src/main/assets/roms/opensbi-riscv64-sifive_u-fw_jump.bin new file mode 100644 index 0000000..1acee86 Binary files /dev/null and b/app/src/main/assets/roms/opensbi-riscv64-sifive_u-fw_jump.bin differ diff --git a/app/src/main/assets/roms/opensbi-riscv64-virt-fw_jump.bin b/app/src/main/assets/roms/opensbi-riscv64-virt-fw_jump.bin new file mode 100644 index 0000000..c62f2b4 Binary files /dev/null and b/app/src/main/assets/roms/opensbi-riscv64-virt-fw_jump.bin differ diff --git a/app/src/main/assets/roms/pvh.bin b/app/src/main/assets/roms/pvh.bin new file mode 100644 index 0000000..8033080 Binary files /dev/null and b/app/src/main/assets/roms/pvh.bin differ diff --git a/app/src/main/assets/roms/pxe-e1000.rom b/app/src/main/assets/roms/pxe-e1000.rom new file mode 100644 index 0000000..2e5f8b2 Binary files /dev/null and b/app/src/main/assets/roms/pxe-e1000.rom differ diff --git a/app/src/main/assets/roms/pxe-eepro100.rom b/app/src/main/assets/roms/pxe-eepro100.rom new file mode 100644 index 0000000..d292e8f Binary files /dev/null and b/app/src/main/assets/roms/pxe-eepro100.rom differ diff --git a/app/src/main/assets/roms/pxe-ne2k_pci.rom b/app/src/main/assets/roms/pxe-ne2k_pci.rom new file mode 100644 index 0000000..62010cb Binary files /dev/null and b/app/src/main/assets/roms/pxe-ne2k_pci.rom differ diff --git a/app/src/main/assets/roms/pxe-pcnet.rom b/app/src/main/assets/roms/pxe-pcnet.rom new file mode 100644 index 0000000..512d6d4 Binary files /dev/null and b/app/src/main/assets/roms/pxe-pcnet.rom differ diff --git a/app/src/main/assets/roms/pxe-rtl8139.rom b/app/src/main/assets/roms/pxe-rtl8139.rom new file mode 100644 index 0000000..67c77fb Binary files /dev/null and b/app/src/main/assets/roms/pxe-rtl8139.rom differ diff --git a/app/src/main/assets/roms/pxe-virtio.rom b/app/src/main/assets/roms/pxe-virtio.rom new file mode 100644 index 0000000..b1ec909 Binary files /dev/null and b/app/src/main/assets/roms/pxe-virtio.rom differ diff --git a/app/src/main/assets/roms/qemu-nsis.bmp b/app/src/main/assets/roms/qemu-nsis.bmp new file mode 100644 index 0000000..ae82cd2 Binary files /dev/null and b/app/src/main/assets/roms/qemu-nsis.bmp differ diff --git a/app/src/main/assets/roms/qemu-nsis.ico b/app/src/main/assets/roms/qemu-nsis.ico new file mode 100644 index 0000000..1d0128c Binary files /dev/null and b/app/src/main/assets/roms/qemu-nsis.ico differ diff --git a/app/src/main/assets/roms/qemu.rsrc b/app/src/main/assets/roms/qemu.rsrc new file mode 100644 index 0000000..e3d205b --- /dev/null +++ b/app/src/main/assets/roms/qemu.rsrc @@ -0,0 +1,1504 @@ +data 'icns' (-16455) { + $"6963 6E73 0000 5DC3 6974 3332 0000 1DB3" /* icns..]√it32...≥ */ + $"0000 0000 FF00 FF00 B000 0F08 1222 3645" /* ....ˇ.ˇ.∞...."6E */ + $"4D56 6063 5A51 473C 2816 0CE8 0019 0416" /* MV`cZQG<(..Ë.... */ + $"3764 94B5 CCDD E7E9 EBEC EDEE ECEB EAE8" /* 7dîµÃ›ÁÈÎÏÌÓÏÎÍË */ + $"E2D4 BEA3 7746 200B E000 0608 2763 A5D0" /* ‚‘æ£wF .‡...'c•– */ + $"E6EE 80F5 8AF6 08F5 F4F0 EAD9 B97C 3B0F" /* ÊÓÄıäˆ.ıÙÍŸπ|;. */ + $"DB00 061C 64AF DAED F0F2 81F1 8BF0 83F1" /* €...dØ⁄ÌÚÅÒãÉÒ */ + $"05EE E3C1 8432 07D5 0007 0635 87CD E8ED" /* .Ó„¡Ñ2.’...5áÕËÌ */ + $"EDEE 97ED 07EE EEED EBDC A551 11D1 0007" /* ÌÓóÌ.ÓÓÌ΋•Q.—.. */ + $"0333 96D9 E6E9 EAE9 9CE8 06E9 E9E8 E1B8" /* .3ñŸÊÈÍÈúË.ÈÈË·∏ */ + $"560E CE00 0628 8CD3 E3E6 E5E4 93E3 80E4" /* V.Œ..(唄ʉì„ĉ */ + $"87E3 06E4 E5E4 DEAE 4A07 CA00 050D 63C8" /* á„.‰Â‰fiÆJ. ...c» */ + $"DFE1 E196 E084 DF86 E004 E1E0 D791 23C8" /* fl··ñ‡Ñfl܇.·‡◊ë#» */ + $"0004 2FA0 D8DC DC84 DA06 D9DA D9D9 DAD9" /* ../†ÿ‹‹Ñ⁄.Ÿ⁄ŸŸ⁄Ÿ */ + $"D987 DA00 D990 DA05 DBDC DBC0 5708 C400" /* Ÿá⁄.Ÿê⁄.€‹€¿W.ƒ. */ + $"1804 54C3 D7D7 D6D6 D7D6 D5D5 D6DF F1DF" /* ..T√◊◊÷÷◊÷’’÷flÒfl */ + $"DADF E5F1 EEDD D5D6 D5D4 81D5 81D6 82D8" /* ⁄flÂÒÓ›’÷’‘Å’Å÷Çÿ */ + $"83D6 80D8 80D6 80D7 04D6 D7D2 8615 C200" /* É÷ÄÿÄ÷Ä◊.÷◊“Ü.¬. */ + $"060E 75CB D4D3 D2D2 80D0 11E0 EAF0 F8FD" /* ..uÀ‘”““Ä–.‡Í¯˝ */ + $"F9F7 FAFB FDFD F7DB CED6 DDD7 D380 D08C" /* ˘˜˙˚˝˝˜€Œ÷›◊”Ä–å */ + $"D286 D104 D2D3 D2A3 29C0 0003 1591 CDCF" /* “Ü—.“”“£)¿...ëÕœ */ + $"80CE 06CC D7DB DEFB FCFD 86FE 0BF5 DBEB" /* ÄŒ.Ã◊€fi˚¸˝Ü˛.ı€Î */ + $"FAF7 F3EB E0D7 D0CD CD86 CE84 CD84 CE03" /* ˙˜Û·◊–ÕÕÜŒÑÕÑŒ. */ + $"CFD0 B739 BE00 0318 96CB CA81 C803 C7DB" /* œ–∑9æ...ñÀ Å».«€ */ + $"FAF9 8AFE 0BFA FCFE FEFD FCFB FAF2 E6D8" /* ˙˘ä˛.˙¸˛˛˝¸˚˙ÚÊÿ */ + $"CD8C C883 CA05 C8C9 CACC BA3F BC00 041B" /* Õå»É .»… Ã∫?º... */ + $"98C7 C5C3 81C4 02C3 C8F1 93FE 09FD FCFA" /* ò«≈√Ń.√»Òì˛∆˝¸˙ */ + $"F3E6 D5CB C3C2 C383 C584 C683 C502 C7B8" /* ÛÊ’À√¬√É≈Ñ∆É≈.«∏ */ + $"42BA 0003 1291 C4C1 84C0 02BC CFFB 96FE" /* B∫...냡ѿ.ºœ˚ñ˛ */ + $"06FC FAF5 E9D5 C2BD 87C0 86BF 02C1 B536" /* .¸˙ıÈ’¬Ωá¿Üø.¡µ6 */ + $"B800 030A 7DC1 BC84 BB03 B9CD D7EE 99FE" /* ∏..¬}¡ºÑª.πÕ◊Óô˛ */ + $"07FC F9EF D4BB BBBE BD82 BC87 BB03 BCC0" /* .¸˘Ô‘ªªæΩǺáª.º¿ */ + $"A825 B600 0304 64BB B981 B880 B704 B5C6" /* ®%∂...dªπÅ∏Ä∑.µ∆ */ + $"F5FA FB9B FE04 FDF9 E6C3 B58F B802 BC97" /* ı˙˚õ˛.˝˘Ê√µè∏.ºó */ + $"15B5 0002 39B2 B582 B480 B201 B5EA A0FE" /* .µ..9≤µÇ¥Ä≤.µÍ†˛ */ + $"04FC F1C9 B1B3 87B2 01B3 B382 B402 B873" /* .¸Ò…±≥á≤.≥≥Ç¥.∏s */ + $"06B3 0002 1899 B385 B002 ADCC FDA2 FE02" /* .≥...ô≥Ö∞.≠Ã˝¢˛. */ + $"F7CB AD8E B002 B1B1 43B2 0002 0671 AE86" /* ˜À≠é∞.±±C≤...qÆÜ */ + $"AC01 ADEC A4FE 02F7 C3A8 81AB 80AA 01AC" /* ¨.≠ϧ˛.˜√®Å´Ä™.¨ */ + $"AB84 AC03 AAAD 9C1C B100 0231 A6A7 80A6" /* ´Ñ¨.™≠ú.±..1¶ßĶ */ + $"82A7 02A4 BEFD 97FE 05DC 9C83 8DAE E085" /* Çß.§æ˝ó˛.‹úÉçÆ‡Ö */ + $"FE06 EEB0 A6A7 A8A6 A685 A800 A781 A602" /* ˛.Ó∞¶ß®¶¶Ö®.ßŶ. */ + $"AD69 04AF 0002 0A7E A681 A281 A302 A2A0" /* ≠i.Ø..¬~¶Å¢Å£.¢† */ + $"E097 FE08 A228 110E 0F14 295A BC83 FE03" /* ‡ó˛.¢(....)ZºÉ˛. */ + $"FDDF A3A1 81A2 80A3 86A2 02A4 A128 AF00" /* ˝fl£°Å¢Ä£Ü¢.§°(Ø. */ + $"013E A286 9E02 9DAE F996 FE02 F228 0181" /* .>¢Üû.ùÆ˘ñ˛.Ú(.Å */ + $"0004 0108 1B72 F582 FE04 FBC3 9A9E 9E82" /* .....rıDz.˚√öûûÇ */ + $"A086 9E03 A0A3 7407 AD00 0209 7C9D 8599" /* †Üû.†£t.≠..∆|ùÖô */ + $"029A 96D4 97FE 01F2 1B85 0002 0B60 F982" /* .öñ‘ó˛.Ú.Ö...`˘Ç */ + $"FE03 EB9E 9898 8899 819A 029B 9C28 AD00" /* ˛.ÎûòòàôÅö.õú(≠. */ + $"012C 9986 9802 93AC F897 FE01 FD72 8600" /* .,ôÜò.쨯ó˛.˝rÜ. */ + $"0109 A882 FE04 FCA6 9497 9780 9885 9781" /* .∆®Ç˛.¸¶îóóÄòÖóÅ */ + $"9801 9D60 AC00 0304 6897 9184 9202 9199" /* ò.ù`¨...hóëÑí.ëô */ + $"E699 FE01 F35B 8600 005D 83FE 01C2 8E8F" /* Êô˛.Û[Ü..]ɲ.¬éè */ + $"9201 8E18 AB00 0317 8B8F 8F83 9003 8F90" /* í.é.´...ãèèÉê.èê */ + $"DBFD 9AFE 02F5 8E1F 8400 0095 83FE 02EE" /* €˝ö˛.ıé.Ñ..ïɲ.Ó */ + $"978D 8590 808E 8090 048E 8E8F 9642 AB00" /* óçÖêÄéÄê.ééèñB´. */ + $"0338 9089 8983 8A02 87AA FC9C FE09 F8E3" /* .8êââÉä.ᙸú˛∆¯„ */ + $"934A 2315 1830 8DF8 84FE 02D9 8F86 828B" /* ìJ#..0ç¯Ñ˛.ŸèÜÇã */ + $"828A 808B 808A 028F 6904 AA00 015D 8C82" /* ÇäÄãÄä.èi.™..]åÇ */ + $"8480 8601 83D3 9EFE 07FD F8F3 EEDF E1F2" /* ÑÄÜ.É”û˛.˝¯ÛÓfl·Ú */ + $"F885 FE04 FCE1 A284 8380 8683 8582 8602" /* ¯Ö˛.¸·¢ÑÉÄÜÉÖÇÜ. */ + $"8781 14A9 0002 0E79 8282 8104 8383 818F" /* áÅ.©...yÇÇÅ.ÉÉÅè */ + $"F498 FE03 FDDE E2F6 83FE 01FD FD88 FE07" /* Ùò˛.˝fi‚ˆÉ˛.˝˝à˛. */ + $"FDF8 D3A3 887E 7F81 8282 8383 0189 2EA9" /* ˝¯”£à~.ÅÇÇÉÉ.â.© */ + $"0002 1E82 7F82 7E03 8080 7BAA 99FE 0BFD" /* ...Ç.Ç~.ÄÄ{™ô˛.˝ */ + $"B46C 5B58 6278 96B7 D4ED FD8A FE08 FCF9" /* ¥l[Xbxñ∑‘Ì˝ä˛.¸˘ */ + $"E5C1 9D84 7A7B 7F83 8003 7F7F 834A A900" /* ¡ùÑz{.ÉÄ...ÉJ©. */ + $"0432 827A 7B7B 8079 037A 7A75 CB9A FE11" /* .2Çz{{Äy.zzuÀö˛. */ + $"FAF5 E8C7 9E72 4B30 2422 2D41 5D7E 9FB6" /* ˙ıË«ûrK0$"-A]~ü∂ */ + $"D2F3 85FE 08FD FBF9 E6C2 967A 7579 817A" /* “ÛÖ˛.˝˚˘Ê¬ñzuyÅz */ + $"047B 797F 5E03 A800 0143 7E80 7781 7602" /* .{y.^.®..C~ÄwÅv. */ + $"757B E99D FE13 FCF9 F6F3 EFD2 A877 4925" /* u{Èù˛.¸˘ˆÛÔ“®wI% */ + $"1109 0B0D 2747 709E C9EB 83FE 07FD FBF7" /* .∆..'Gpû…Îɲ.˝˚˜ */ + $"D8A7 8072 7481 7602 776B 0BA8 0001 4F77" /* ÿßÄrtÅv.wk.®..Ow */ + $"8073 8172 0270 8DFC A2FE 13FC FAF6 F3F1" /* ÄsÅr.p縢˛.¸˙ˆÛÒ */ + $"D5AE 7F51 270D 0609 0C20 3C62 8FBB E181" /* ’Æ.Q'..∆. ^YYÄX.WbÍ´˛.› */ + $"A57D 695C 5958 5757 5857 595F 6873 7E8C" /* •}i\YXWWXWY_hs~å */ + $"98A5 AFAE A07C 5B56 639E 5F0E A800 0330" /* ò•ØƆ|[Vcû_.®..0 */ + $"5955 5580 5402 507C FDA9 FE08 DA8F 5F54" /* YUUÄT.P|˝©˛.⁄è_T */ + $"5354 5455 5580 5681 5581 5480 5507 5454" /* STTUUÄVÅUÅTÄU.TT */ + $"5556 5557 4E07 A800 0122 5680 5203 5151" /* UVUWN.®.."VÄR.QQ */ + $"4C9C A8FE 05E1 955D 5051 5080 5183 5282" /* Lú®˛.·ï]PQPÄQÉRÇ */ + $"5180 5208 5151 5051 5152 5254 3FA9 0000" /* QÄR.QQPQQRRT?©.. */ + $"1581 5003 4F4F 49B4 A6FE 03D4 905D 4D85" /* .ÅP.OOI¥¶˛.‘ê]MÖ */ + $"4F82 5083 4F01 5050 844F 0152 2EA9 0002" /* OÇPÉO.PPÑO.R.©.. */ + $"0A45 4B81 4A01 49CE A3FE 06F2 BB7B 5349" /* ¬EKÅJ.IŒ£˛.Úª{SI */ + $"4A4A 804B 8D4A 824B 814A 014E 1BAA 0001" /* JJÄKçJÇKÅJ.N.™.. */ + $"324A 8047 0246 4EE4 A1FE 06E3 9E65 4944" /* 2JÄG.FN‰°˛.„ûeID */ + $"4647 8248 8547 8348 0147 4783 4880 4701" /* FGÇHÖGÉH.GGÉHÄG. */ + $"440C AA00 011C 4880 4502 4154 F19F FE05" /* D.™...HÄE.ATÒü˛. */ + $"DE8C 5644 4244 8043 8245 8344 8245 8644" /* fiåVDBDÄCÇEÉDÇEÜD */ + $"8145 0147 33AB 0001 0C3F 8041 023F 5EFB" /* ÅE.G3´...?ÄA.?^˚ */ + $"9DFE 02EE 9552 8040 8041 8540 8041 0140" /* ù˛.ÓïRÄ@ÄAÖ@ÄA.@ */ + $"4080 4180 4080 4182 4081 4101 4420 AC00" /* @ÄAÄ@ÄAÇ@ÅA.D ¨. */ + $"052C 403E 3E38 679D FE04 C35D 3C3D 3E82" /* .,@>>8gù˛.√]<=>Ç */ + $"4080 3E80 3F82 4080 3F80 3E8B 3F01 3D0C" /* @Ä>Ä?Ç@Ä?Ä>ã?.=. */ + $"AC00 0513 3D3B 3A34 749C FE02 A743 3880" /* ¨...=;:4tú˛.ßC8Ä */ + $"3A80 3B82 3A80 3982 3B83 3A80 3B87 3A01" /* :Ä;Ç:Ä9Ç;É:Ä;á:. */ + $"3E26 AD00 0504 2E38 3731 789B FE03 9C32" /* >&≠....871xõ˛.ú2 */ + $"3536 8037 8038 8337 0136 3688 3783 3680" /* 56Ä7Ä8É7.66à7É6Ä */ + $"3781 3601 380F AE00 0415 3634 2D77 9AFE" /* 7Å6.8.Æ...64-wö˛ */ + $"02BF 3432 8033 8034 0135 3583 3480 3301" /* .ø42Ä3Ä4.55É4Ä3. */ + $"3434 8335 8B34 0136 25AF 0004 0327 322B" /* 44É5ã4.6%Ø...'2+ */ + $"6F99 FE02 F24B 2C81 3080 3180 329B 3101" /* oô˛.ÚK,Å0Ä1Ä2õ1. */ + $"300D B000 030E 2F28 6099 FE01 9C27 882D" /* 0.∞.../(`ô˛.ú'à- */ + $"802E 882D 822E 872D 0130 1DB2 0003 1B29" /* Ä.à-Ç.á-.0.≤...) */ + $"4AFC 97FE 02F9 4B26 812A 842B 802C 822B" /* J¸ó˛.˘K&Å*Ñ+Ä,Ç+ */ + $"802A 802B 802C 852B 802C 022B 2809 B200" /* Ä*Ä+Ä,Ö+Ä,.+(∆≤. */ + $"0306 2137 E997 FE02 CA28 2681 2784 2880" /* ..!7Èó˛. (&Å'Ñ(Ä */ + $"2997 2800 10B4 0002 0D25 C897 FE02 931D" /* )ó(..¥...%»ó˛.ì. */ + $"2584 248D 2582 2483 2581 2401 2718 B600" /* %Ñ$ç%Ç$É%Å$.'.∂. */ + $"0110 B597 FE01 681B 8521 8422 8023 8B22" /* ..µó˛.h.Ö!Ñ"Ä#ã" */ + $"8023 8022 0223 1C04 B700 00A2 97FE 014A" /* Ä#Ä".#..∑..¢ó˛.J */ + $"1A85 1E84 1F80 2086 1F80 1E82 1F80 2001" /* .Ö.Ñ.Ä Ü.Ä.Ç.Ä . */ + $"1C08 B800 0094 96FE 02FB 3C19 841C 881D" /* ..∏..îñ˛.˚<.Ñ.à. */ + $"801E 861D 801C 811D 011C 09B9 0000 8C96" /* Ä.Ü.Ä.Å...∆π..åñ */ + $"FE02 F434 1688 1994 1A03 191A 190A BA00" /* ˛.Ù4.à.î.....¬∫. */ + $"0085 96FE 02F4 3114 8816 8717 8018 8717" /* .Öñ˛.Ù1.à.á.Ä.á. */ + $"0218 1609 BB00 007C 96FE 02F7 3111 8B14" /* ...∆ª..|ñ˛.˜1.ã. */ + $"8715 8016 8415 0113 07BC 0000 6F97 FE01" /* á.Ä.Ñ....º..oó˛. */ + $"3A0E 9D12 0213 0E04 BD00 004C 97FE 0148" /* :.ù.....Ω..Ló˛.H */ + $"0A8B 0F8F 1000 0BBF 0001 22F8 96FE 0157" /* ¬ã.è...ø.."¯ñ˛.W */ + $"0795 0D83 0E01 0D07 C000 0104 BB96 FE01" /* .ï.É....¿...ªñ˛. */ + $"7504 9A0B 0109 03C2 0000 3A96 FE01 9D03" /* u.ö..∆.¬..:ñ˛.ù. */ + $"9809 0107 04C5 0000 7295 FE01 A500 9706" /* ò∆...≈..rï˛.•.ó. */ + $"0003 C800 0160 F993 FE02 C606 0094 03CC" /* ..»..`˘ì˛.∆..î.à */ + $"0001 47EE 92FE 01EC 15E5 0001 37E9 92FE" /* ..GÓí˛.Ï.Â..7Èí˛ */ + $"0037 E600 0131 E691 FE00 6BE7 0001 32EC" /* .7Ê..1Êë˛.kÁ..2Ï */ + $"90FE 00A6 E800 0139 E68F FE01 E010 E800" /* ê˛.¶Ë..9Êè˛.‡.Ë. */ + $"0141 EC8F FE00 37E9 0001 4BF3 8EFE 007A" /* .AÏè˛.7È..KÛé˛.z */ + $"EA00 0164 F78D FE01 C305 EA00 0181 F98C" /* Í..d˜ç˛.√.Í..Å˘å */ + $"FE01 F423 EA00 0209 9EFB 8CFE 0066 EB00" /* ˛.Ù#Í..∆û˚å˛.fÎ. */ + $"020F B9FD 8BFE 01BA 04EB 0001 1CD5 8BFE" /* ..π˝ã˛.∫.Î...’ã˛ */ + $"01F4 23EC 0001 30E8 8BFE 0067 ED00 014C" /* .Ù#Ï..0Ëã˛.gÌ..L */ + $"F58A FE01 BB04 ED00 016F F989 FE01 F424" /* ıä˛.ª.Ì..o˘â˛.Ù$ */ + $"ED00 0206 A1FC 89FE 0067 EE00 0113 CD89" /* Ì...°¸â˛.gÓ...Õâ */ + $"FE01 BE06 EE00 012E EA88 FE01 F624 EF00" /* ˛.æ.Ó...Íà˛.ˆ$Ô. */ + $"015A F888 FE00 6CEF 0002 038B FB87 FE01" /* .Z¯à˛.lÔ...ã˚á˛. */ + $"C206 EF00 010F BC87 FE01 F828 F000 0125" /* ¬.Ô...ºá˛.¯(..% */ + $"E687 FE00 6DF1 0001 59F9 86FE 01BD 04F0" /* Êá˛.mÒ..Y˘Ü˛.Ω. */ + $"0002 049D FD85 FE01 F320 F100 0117 D786" /* ...ù˝Ö˛.Û Ò...◊Ü */ + $"FE00 5EF2 0001 42F6 85FE 00A9 F300 0182" /* ˛.^Ú..BˆÖ˛.©Û..Ç */ + $"FB84 FE01 E311 F200 010F C585 FE00 35F3" /* ˚Ñ˛.„.Ú...≈Ö˛.5Û */ + $"0001 31F1 84FE 0074 F400 0176 F983 FE01" /* ..1ÒÑ˛.tÙ..v˘É˛. */ + $"B601 F300 010E C383 FE01 E310 F400 0138" /* ∂.Û...√ɲ.„.Ù..8 */ + $"F082 FE01 FB2A F500 0184 FB82 FE00 4FF5" /* Dz.˚*ı..Ñ˚Dz.Oı */ + $"0001 13CD 82FE 007D F600 0145 F481 FE00" /* ...ÕDz.}ˆ..EÙÅ˛. */ + $"A1F6 0002 049A FD80 FE01 BA01 F600 0121" /* °ˆ...ö˝Ä˛.∫.ˆ..! */ + $"E480 FE01 D209 F700 056F FAFE FEE5 11F7" /* ‰Ä˛.“∆˜..o˙˛˛Â.˜ */ + $"0005 0ECA FEFE F41D F800 0447 F5FE FE2C" /* ... ˛˛Ù.¯..Gı˛˛, */ + $"F800 0406 A5FD FE40 F900 0329 E0FE 5BFA" /* ¯...•˝˛@˘..)‡˛[˙ */ + $"0002 3BF7 7EFB 0001 C2A8 FB00 026A CB01" /* ..;˜~˚..¬®˚..jÀ. */ + $"FA00 0223 D210 FA00 0204 9920 FB00 0129" /* ˙..#“.˙...ô ˚..) */ + $"1EFF 00FF 00FF 00FF 00FF 00FF 00FF 00FF" /* .ˇ.ˇ.ˇ.ˇ.ˇ.ˇ.ˇ.ˇ */ + $"00A8 00FF 00FF 00B0 000F 0812 2236 454D" /* .®.ˇ.ˇ.∞...."6EM */ + $"5660 635A 5147 3C28 160C E800 1904 1637" /* V`cZQG<(..Ë....7 */ + $"6494 B5CC DDE7 E9EB ECED EEEC EBEA E8E2" /* dîµÃ›ÁÈÎÏÌÓÏÎÍË‚ */ + $"D4BE A377 4620 0BE0 0006 0827 63A5 D0E6" /* ‘æ£wF .‡...'c•–Ê */ + $"EE80 F58A F608 F5F4 F0EA D9B9 7C3B 0FDB" /* ÓÄıäˆ.ıÙÍŸπ|;.€ */ + $"0006 1C64 AFDA EDF0 F281 F18B F083 F105" /* ...dØ⁄ÌÚÅÒãÉÒ. */ + $"EEE3 C184 3207 D500 0706 3587 CDE8 EDED" /* Ó„¡Ñ2.’...5áÕËÌÌ */ + $"EE97 ED07 EEEE EDEB DCA5 5111 D100 0703" /* ÓóÌ.ÓÓÌ΋•Q.—... */ + $"3396 D9E6 E9EA E99C E806 E9E9 E8E1 B856" /* 3ñŸÊÈÍÈúË.ÈÈË·∏V */ + $"0ECE 0006 288C D3E3 E6E5 E493 E380 E487" /* .Œ..(唄ʉì„ĉá */ + $"E306 E4E5 E4DE AE4A 07CA 0005 0D63 C8DF" /* „.‰Â‰fiÆJ. ...c»fl */ + $"E1E1 96E0 84DF 86E0 04E1 E0D7 9123 C800" /* ··ñ‡Ñfl܇.·‡◊ë#». */ + $"042F A0D8 DCDC 82DA 08DB D9DE DCDE DFDC" /* ./†ÿ‹‹Ç⁄.€Ÿfi‹fifl‹ */ + $"DEDE 87DA 00D9 90DA 05DB DCDB C057 08C4" /* fifiá⁄.Ÿê⁄.€‹€¿W.ƒ */ + $"0004 0454 C3D7 D780 D614 D7DA DBD9 BC82" /* ...T√◊◊Ä÷.◊⁄€ŸºÇ */ + $"BDCA BCA7 8185 C2DA D6D8 D9D8 D6D6 D581" /* Ω ºßÅÖ¬⁄÷ÿŸÿ÷÷’Å */ + $"D682 D883 D680 D880 D680 D704 D6D7 D286" /* ÷ÇÿÉ÷ÄÿÄ÷Ä◊.÷◊“Ü */ + $"15C2 001F 0E75 CBD4 D3D2 D2D4 D6D3 AC8C" /* .¬...uÀ‘”““‘÷”¨å */ + $"7E65 5362 685D 5753 5267 B7D8 C5B1 C2CD" /* ~eSbh]WSRg∑ÿ≈±¬Õ */ + $"D4D7 D5D3 8BD2 86D1 04D2 D3D2 A329 C000" /* ‘◊’”ã“Ü—.“”“£)¿. */ + $"0315 91CD CF80 CE0B D0B5 ABA5 5A54 5352" /* ..ë՜Č.–µ´•ZTSR */ + $"5151 5252 8151 0C66 AA81 5964 6F83 9EB5" /* QQRRÅQ.f™ÅYdoÉûµ */ + $"C9D2 D2CF 85CE 84CD 84CE 03CF D0B7 39BE" /* …““œÖŒÑÕÑŒ.œ–∑9æ */ + $"0003 1896 CBCA 81C8 06CD 9E57 5D50 5151" /* ...ñÀ Å».ÕûW]PQQ */ + $"8552 1151 515A 5551 5152 5456 5E6D 89A6" /* ÖR.QQZUQQRTV^mⶠ*/ + $"C0CD CDCB C988 C883 CA05 C8C9 CACC BA3F" /* ¿ÕÕÀ…à»É .»… Ã∫? */ + $"BC00 041B 98C7 C5C3 82C4 02BD 684F 8A52" /* º...ò«≈√ǃ.ΩhOäR */ + $"0051 8152 0C51 5152 5254 5A67 82A2 BAC6" /* .QÅR.QQRRTZgÇ¢∫∆ */ + $"C8C6 83C5 84C6 83C5 02C7 B842 BA00 0312" /* »∆É≈Ñ∆É≈.«∏B∫... */ + $"91C4 C184 C003 C6A2 5551 9252 0951 5152" /* 냡ѿ.∆¢UQíR∆QQR */ + $"5359 6379 9ABA C387 C086 BF02 C1B5 36B8" /* SYcyö∫√á¿Üø.¡µ6∏ */ + $"0003 0A7D C1BC 84BB 04BF 9E8E 6A50 9552" /* ..¬}¡ºÑª.øûéjPïR */ + $"0A51 5152 5357 6B95 BBBF BEBD 82BC 87BB" /* ¬QQRSWkïªøæΩǺ᪠*/ + $"03BC C0A8 25B6 0003 0464 BBB9 81B8 80B7" /* .º¿®%∂...dªπÅ∏Ä∑ */ + $"05BA A35E 5656 5198 5280 5103 5672 A8BB" /* .∫£^VVQòRÄQ.Vr®ª */ + $"8FB8 02BC 9715 B500 0239 B2B5 82B4 06B2" /* è∏.ºó.µ..9≤µÇ¥.≤ */ + $"B2B3 B16B 5051 9D52 0551 5361 95B8 B387" /* ≤≥±kPQùR.QSaï∏≥á */ + $"B201 B3B3 82B4 02B8 7306 B300 0218 99B3" /* ≤.≥≥Ç¥.∏s.≥...ô≥ */ + $"85B0 03B3 8E51 519F 5204 5150 5A8D B28E" /* Ö∞.≥éQQüR.QPZç≤é */ + $"B002 B1B1 43B2 0002 0671 AE85 AC03 ADAA" /* ∞.±±C≤...qÆÖ¨.≠™ */ + $"654F 9652 0054 8056 0155 5383 5203 5158" /* eOñR.TÄV.USÉR.QX */ + $"92AE 81AB 80AA 01AC AB84 AC03 AAAD 9C1C" /* íÆÅ´Ä™.¨´Ñ¨.™≠ú. */ + $"B100 0231 A6A7 80A6 82A7 01AA 8F97 5208" /* ±..1¶ßĶÇß.™èóR. */ + $"5548 342D 313B 4954 5582 5207 5060 9EA9" /* UH4-1;ITUÇR.P`û© */ + $"A7A8 A6A6 85A8 00A7 81A6 02AD 6904 AF00" /* ß®¶¶Ö®.ßŶ.≠i.Ø. */ + $"020A 7EA6 81A2 82A3 02A4 6C50 9552 0B55" /* .¬~¶Å¢Ç£.§lPïR.U */ + $"3610 0605 0506 1021 3F55 5381 5201 516D" /* 6......!?USÅR.Qm */ + $"83A2 80A3 86A2 02A4 A128 AF00 013E A286" /* ɢģܢ.§°(Ø..>¢Ü */ + $"9E02 A191 5595 5203 534F 1101 8100 0501" /* û.°ëUïR.SO..Å... */ + $"030B 2750 5380 5205 5152 81A1 9E9E 82A0" /* ..'PSÄR.QRÅ°ûûdž */ + $"869E 03A0 A374 07AD 0002 097C 9D85 9903" /* Üû.†£t.≠..∆|ùÖô. */ + $"9A9E 6F50 9552 0253 4F0D 8500 0104 2282" /* öûoPïR.SO.Ö..."Ç */ + $"5204 505F 9899 9888 9981 9A02 9B9C 28AD" /* R.P_òôòàôÅö.õú(≠ */ + $"0001 2C99 8798 0287 5651 9652 0154 2886" /* ..,ôáò.áVQñR.T(Ü */ + $"0002 0339 5581 5201 538A 8097 8098 8597" /* ...9UÅR.SäÄóÄòÖó */ + $"8198 019D 60AC 0003 0468 9791 8492 0393" /* Åò.ù`¨...hóëÑí.ì */ + $"8E60 5098 5201 5021 8600 0121 5681 5202" /* é`PòR.P!Ü..!VÅR. */ + $"5074 968F 9201 8E18 AB00 0317 8B8F 8F84" /* Ptñèí.é.´...ãèèÑ */ + $"9002 8F64 5099 5203 5351 310F 8400 0133" /* ê.èdPôR.SQ1.Ñ..3 */ + $"5581 5202 5159 8786 9080 8E80 9004 8E8E" /* UÅR.QYáÜêÄéÄê.éé */ + $"8F96 42AB 0003 3890 8989 838A 038D 7B51" /* èñB´..8êââÉä.ç{Q */ + $"519B 5209 544A 331C 0F0B 0C14 3051 8352" /* QõR∆TJ3.....0QÉR */ + $"0350 6288 8D82 8B82 8A80 8B80 8A02 8F69" /* .PbàçÇãÇäÄãÄä.èi */ + $"04AA 0001 5D8C 8284 8086 0288 6350 9852" /* .™..]åÇÑÄÜ.àcPòR */ + $"0153 5381 5206 5452 4C49 494F 5385 5207" /* .SSÅR.TRLIIOSÖR. */ + $"515E 7A87 8887 8686 8385 8286 0287 8114" /* Q^záàáÜÜÉÖÇÜ.áÅ. */ + $"A900 020E 7982 8281 8083 017F 5699 5203" /* ©...yÇÇÅÄÉ..VôR. */ + $"494A 5054 8056 0255 5453 8952 0651 5464" /* IJPTÄV.UTSâR.QTd */ + $"7581 8383 8382 8383 0189 2EA9 0002 1E82" /* uÅÉÉÉÇÉÉ.â.©...Ç */ + $"7F82 7E04 8080 816F 5098 520C 533D 2621" /* .Ç~.ÄÄÅoPòR.S=&! */ + $"2123 2A33 3E46 4E51 5580 5602 5554 5383" /* !#*3>FNQUÄV.UTSÉ */ + $"5208 5153 5A66 737D 8080 7F83 8003 7F7F" /* R.QSZfs}ÄÄ.ÉÄ... */ + $"834A A900 0432 827A 7B7B 8079 047A 7A7C" /* ÉJ©..2Çz{{Äy.zz| */ + $"6050 9A52 1551 4B41 3628 1D13 100E 1319" /* `PöR.QKA6(...... */ + $"222C 363E 4550 5556 5654 5380 5208 5151" /* ",6>EPUVVTSÄR.QQ */ + $"5358 6471 797B 7B81 7A04 7B79 7F5E 03A8" /* SXdqy{{Åz.{y.^.® */ + $"0001 437E 8077 8276 0274 5851 9B52 2251" /* ..C~ÄwÇv.tXQõR"Q */ + $"5253 5352 4D44 392A 1B10 0903 0304 101B" /* RSSRMD9*..∆..... */ + $"2836 434E 5356 5655 5352 5151 545D 6874" /* (6CNSVVUSRQQT]ht */ + $"7877 8176 0277 6B0B A800 014F 7780 7381" /* xwÅv.wk.®..OwÄsÅ */ + $"7201 736B A452 1C53 5352 4D47 3A2C 1E10" /* r.sk§R.SSRMG:,.. */ + $"0602 0304 0E17 2332 3F4A 5256 5553 5152" /* ......#2?JRVUSQR */ + $"5662 6F74 8073 0274 6F0F A800 0156 7281" /* VbotÄs.to.®..VrÅ */ + $"7080 6F02 7062 51A8 521D 5353 524E 4536" /* pÄo.pbQ®R.SSRNE6 */ + $"2616 0C05 0202 030B 172B 414F 5456 5553" /* &........+AOTVUS */ + $"5362 6F70 706F 7017 A700 0206 596E 816B" /* Sboppop.ß...YnÅk */ + $"806A 026C 5B51 AD52 1853 5350 4A43 3A2B" /* Äj.l[Q≠R.SSPJC:+ */ + $"1A0F 0802 040E 1922 324B 5652 5969 6C6B" /* ......."2KVRYilk */ + $"6D1B A700 0306 586A 6880 6780 6601 6754" /* m.ß...XjhÄgÄf.gT */ + $"B252 8053 1151 4C46 3A2D 1E11 0603 0D2E" /* ≤RÄS.QLF:-...... */ + $"5153 5564 686B 1CA7 0003 0655 6765 8364" /* QSUdhk.ß...UgeÉd */ + $"0060 B952 8053 0B4F 452F 1402 1849 5558" /* .`πRÄS.OE/...IUX */ + $"6468 1BA7 0002 0450 6381 6103 6060 615C" /* dh.ß...PcÅa.``a\ */ + $"BE52 0954 5039 100E 3D53 5D63 18A8 0001" /* æR∆TP9..=S]c.®.. */ + $"4860 825E 025D 5D56 AF52 0255 5756 8058" /* H`Ç^.]]VØR.UWVÄX */ + $"0357 5555 5384 5207 534B 1F23 5456 5E12" /* .WUUSÑR.SK.#TV^. */ + $"A800 033E 5E59 5980 5801 5958 AC52 0353" /* ®..>^YYÄX.YX¨R.S */ + $"5558 5888 5900 5880 5609 5452 5557 5A59" /* UXXàY.XÄV∆TRUWZY */ + $"5956 560E A800 0330 5955 5580 5401 5554" /* YVV.®..0YUUÄT.UT */ + $"AB52 0254 5555 8054 0155 5580 5680 5585" /* ´R.TUUÄT.UUÄVÄUÖ */ + $"5680 5504 5656 584D 07A8 0001 2256 8052" /* VÄU.VVXM.®.."VÄR */ + $"8051 AD52 8251 8352 8251 8052 8251 0352" /* ÄQ≠RÇQÉRÇQÄRÇQ.R */ + $"5254 3FA9 0000 1581 5080 4F00 51A6 5202" /* RT?©...ÅPÄO.Q¶R. */ + $"5150 4F80 5083 4F82 5083 4F01 5050 844F" /* QPOÄPÉOÇPÉO.PPÑO */ + $"0152 2EA9 0002 0A45 4B82 4A00 50A2 5207" /* .R.©..¬EKÇJ.P¢R. */ + $"5351 4F4E 4A4B 4A4A 804B 8D4A 824B 814A" /* SQONJKJJÄKçJÇKÅJ */ + $"014E 1BAA 0001 324A 8147 0148 51A0 5204" /* .N.™..2JÅG.HQ†R. */ + $"5351 4E4A 4780 4682 4885 4783 4801 4747" /* SQNJGÄFÇHÖGÉH.GG */ + $"8348 8047 0144 0CAA 0001 1C48 8045 0244" /* ÉHÄG.D.™...HÄE.D */ + $"4551 9E52 0653 504B 4543 4344 8043 8245" /* EQûR.SPKECCDÄCÇE */ + $"8344 8245 8644 8145 0147 33AB 0001 0C3F" /* ÉDÇEÜDÅE.G3´...? */ + $"8041 0140 449D 5204 5352 4942 4082 4185" /* ÄA.@DùR.SRIB@ÇAÖ */ + $"4080 4101 4040 8041 8040 8041 8240 8141" /* @ÄA.@@ÄAÄ@ÄAÇ@ÅA */ + $"0144 20AC 0001 2C40 803E 0042 9C52 0553" /* .D ¨..,@Ä>.BúR.S */ + $"4D41 3E3F 3F82 4080 3E80 3F82 4080 3F80" /* MA>??Ç@Ä>Ä?Ç@Ä?Ä */ + $"3E8B 3F01 3D0C AC00 0613 3D3B 3A39 4153" /* >ã?.=.¨...=;:9AS */ + $"9A52 0353 493A 3980 3A80 3B82 3A80 3982" /* öR.SI:9Ä:Ä;Ç:Ä9Ç */ + $"3B83 3A80 3B87 3A01 3E26 AD00 0604 2E38" /* ;É:Ä;á:.>&≠....8 */ + $"3736 4153 9952 0153 4680 3680 3780 3883" /* 76ASôR.SFÄ6Ä7Ä8É */ + $"3701 3636 8837 8336 8037 8136 0138 0FAE" /* 7.66à7É6Ä7Å6.8.Æ */ + $"0005 1536 3433 3F53 9852 0353 4933 3280" /* ...643?SòR.SI32Ä */ + $"3380 3401 3535 8334 8033 0134 3483 358B" /* 3Ä4.55É4Ä3.44É5ã */ + $"3401 3625 AF00 0503 2732 303B 5398 5202" /* 4.6%Ø...'20;SòR. */ + $"5135 2F81 3080 3180 329B 3101 300D B000" /* Q5/Å0Ä1Ä2õ1.0.∞. */ + $"040E 2F2C 3853 9752 0254 412C 882D 802E" /* ../,8SóR.TA,à-Ä. */ + $"882D 822E 872D 0130 1DB2 0003 1B2C 3251" /* à-Ç.á-.0.≤...,2Q */ + $"9752 0251 3129 812A 842B 802C 822B 802A" /* óR.Q1)Å*Ñ+Ä,Ç+Ä* */ + $"802B 802C 852B 802C 022B 2809 B200 0406" /* Ä+Ä,Ö+Ä,.+(∆≤... */ + $"242D 4D53 9552 0153 4983 2784 2880 2997" /* $-MSïR.SIÉ'Ñ(Ä)ó */ + $"2800 10B4 0003 0D26 4853 9552 0354 3D22" /* (..¥...&HSïR.T=" */ + $"2584 248D 2582 2483 2581 2401 2718 B600" /* %Ñ$ç%Ç$É%Å$.'.∂. */ + $"0212 4454 9552 0254 3220 8521 8422 8023" /* ..DTïR.T2 Ö!Ñ"Ä# */ + $"8B22 8023 8022 0223 1C04 B700 0138 5595" /* ã"Ä#Ä".#..∑..8Uï */ + $"5202 532A 1D85 1E84 1F80 2086 1F80 1E82" /* R.S*.Ö.Ñ.Ä Ü.Ä.Ç */ + $"1F80 2001 1C08 B800 0132 5695 5202 5125" /* .Ä ...∏..2VïR.Q% */ + $"1B84 1C88 1D80 1E86 1D80 1C81 1D01 1C09" /* .Ñ.à.Ä.Ü.Ä.Å...∆ */ + $"B900 012F 5695 5201 5021 8919 941A 0319" /* π../VïR.P!â.î... */ + $"1A19 0ABA 0001 2D56 9552 014F 1E89 1687" /* ..¬∫..-VïR.O.â.á */ + $"1780 1887 1702 1816 09BB 0001 2A56 9552" /* .Ä.á....∆ª..*VïR */ + $"0250 1C13 8B14 8715 8016 8415 0113 07BC" /* .P..ã.á.Ä.Ñ....º */ + $"0001 2756 9652 011E 109D 1202 130E 04BD" /* ..'VñR...ù.....Ω */ + $"0001 1C56 9552 0254 210E 8B0F 8F10 000B" /* ...VïR.T!.ã.è... */ + $"BF00 010E 5095 5202 5524 0B95 0D83 0E01" /* ø...PïR.U$.ï.É.. */ + $"0D07 C000 0203 3E55 9452 0256 2B09 9A0B" /* ..¿...>UîR.V+∆ö. */ + $"0109 03C2 0002 1654 5393 5202 5535 0698" /* .∆.¬...TSìR.U5.ò */ + $"0901 0704 C500 0227 5553 9252 0255 3704" /* ∆...≈..'USíR.U7. */ + $"9706 0003 C800 0222 5253 9152 0254 4104" /* ó...».."RSëR.TA. */ + $"9503 CC00 021A 4D54 9052 0253 4D09 E500" /* ï.Ã...MTêR.SM∆Â. */ + $"0216 4D54 9052 0154 15E6 0002 134B 548F" /* ..MTêR.T.Ê...KTè */ + $"5201 5625 E700 0214 4E54 8E52 0155 36E8" /* R.V%Á...NTéR.U6Ë */ + $"0002 154C 538D 5202 5348 08E8 0002 184D" /* ...LSçR.SH.Ë...M */ + $"538D 5201 5415 E900 021C 5053 8C52 0156" /* SçR.T.È...PSåR.V */ + $"2AEA 0001 2353 8C52 0154 3FEB 0001 2D54" /* *Í..#SåR.T?Î..-T */ + $"8C52 0150 0FEA 0002 0434 558B 5201 5623" /* åR.P.Í...4UãR.V# */ + $"EB00 0208 3C54 8A52 0155 3CEC 0002 0D46" /* Î...Ô.. */ + $"134D 5387 5201 5010 EF00 011F 5387 5201" /* .MSáR.P.Ô...SáR. */ + $"5625 F000 012F 5586 5201 553F F000 0207" /* V%../UÜR.U?... */ + $"3E54 8652 0151 10F0 0002 0F4D 5385 5201" /* >TÜR.Q....MSÖR. */ + $"5625 F100 011E 5485 5201 553E F100 0203" /* V%Ò...TÖR.U>Ò... */ + $"3455 8452 0253 500E F100 020B 4654 8452" /* 4UÑR.SP.Ò...FTÑR */ + $"0156 21F2 0001 1951 8452 0155 38F3 0001" /* .V!Ú...QÑR.U8Û.. */ + $"2C55 8352 0253 4908 F200 0208 4054 8352" /* ,UÉR.SI.Ú...@TÉR */ + $"0153 15F3 0001 134F 8352 0156 27F4 0001" /* .S.Û...OÉR.V'Ù.. */ + $"2854 8252 0155 3DF4 0002 0741 5481 5202" /* (TÇR.U=Ù...ATÅR. */ + $"5349 08F4 0001 1550 8252 0151 11F5 0001" /* SI.Ù...PÇR.Q.ı.. */ + $"2C55 8152 0156 1BF5 0002 0944 5480 5201" /* ,UÅR.V.ı..∆DTÄR. */ + $"562A F600 0019 8152 0156 35F7 0005 3456" /* V*ˆ...ÅR.V5˜..4V */ + $"5252 553E F700 060E 4B53 5254 4405 F700" /* RRU>˜...KSRTD.˜. */ + $"0526 5552 5349 08F7 0005 0842 5453 4E0D" /* .&URSI.˜...BTSN. */ + $"F800 0019 8052 0011 F800 0403 3755 5418" /* ¯...ÄR..¯...7UT. */ + $"F900 0310 4A57 20FA 0002 1552 2AFB 0001" /* ˘...JW ˙...R*˚.. */ + $"3E37 FB00 0125 43FB 0002 0E44 07FA 0002" /* >7˚..%C˚...D.˙.. */ + $"0333 0EFB 0001 0F0D FF00 FF00 FF00 FF00" /* .3.˚....ˇ.ˇ.ˇ.ˇ. */ + $"FF00 FF00 FF00 FF00 A800 FF00 FF00 B000" /* ˇ.ˇ.ˇ.ˇ.®.ˇ.ˇ.∞. */ + $"0F08 1222 3645 4D56 6063 5A51 473C 2816" /* ..."6EMV`cZQG<(. */ + $"0CE8 0019 0416 3764 94B5 CCDD E7E9 EBEC" /* .Ë....7dîµÃ›ÁÈÎÏ */ + $"EDEE ECEB EAE8 E2D4 BEA3 7746 200B E000" /* ÌÓÏÎÍË‚‘æ£wF .‡. */ + $"0608 2763 A5D0 E6EE 80F5 8AF6 08F5 F4F0" /* ..'c•–ÊÓÄıäˆ.ıÙ */ + $"EAD9 B97C 3B0F DB00 061C 64AF DAED F0F2" /* ÍŸπ|;.€...dØ⁄ÌÚ */ + $"81F1 8BF0 83F1 05EE E3C1 8432 07D5 0007" /* ÅÒãÉÒ.Ó„¡Ñ2.’.. */ + $"0635 87CD E8ED EDEE 97ED 07EE EEED EBDC" /* .5áÕËÌÌÓóÌ.ÓÓÌ΋ */ + $"A551 11D1 0007 0333 96D9 E6E9 EAE9 9CE8" /* •Q.—...3ñŸÊÈÍÈúË */ + $"06E9 E9E8 E1B8 560E CE00 0628 8CD3 E3E6" /* .ÈÈË·∏V.Œ..(å”„Ê */ + $"E5E4 93E3 80E4 87E3 06E4 E5E4 DEAE 4A07" /* ‰ì„ĉá„.‰Â‰fiÆJ. */ + $"CA00 050D 63C8 DFE1 E196 E084 DF86 E004" /* ...c»fl··ñ‡Ñfl܇. */ + $"E1E0 D791 23C8 0004 2FA0 D8DC DC81 DA06" /* ·‡◊ë#»../†ÿ‹‹Å⁄. */ + $"DBDC D9E0 DEE0 E480 DF87 DA00 D990 DA05" /* €‹Ÿ‡fi‡‰Äflá⁄.Ÿê⁄. */ + $"DBDC DBC0 5708 C400 0404 54C3 D7D7 80D6" /* €‹€¿W.ƒ...T√◊◊Ä÷ */ + $"14D7 DFDF DDA5 45A8 C1A4 7E43 4DB0 DED6" /* .◊flfl›•E®¡§~CM∞fi÷ */ + $"D9DD D9D8 D6D5 81D6 82D8 83D6 80D8 80D6" /* Ÿ›Ÿÿ÷’Å÷ÇÿÉ÷ÄÿÄ÷ */ + $"80D7 04D6 D7D2 8615 C200 1F0E 75CB D4D3" /* Ä◊.÷◊“Ü.¬...uÀ‘” */ + $"D2D2 D6DA D489 563E 1305 131C 130D 0506" /* ““÷⁄‘âV>........ */ + $"1E9F E0BA 94B4 C9D7 DBD7 D38B D286 D104" /* .ü‡∫◊€◊”ã“Ü—. */ + $"D2D3 D2A3 29C0 0003 1591 CDCF 80CE 06D2" /* “”“£)¿...ë՜Č.“ */ + $"9F8E 800F 0805 8500 0D01 1B8B 4311 152B" /* üéÄ...Ö....ãC..+ */ + $"4872 A0C4 D7D7 D185 CE84 CD84 CE03 CFD0" /* Hr†ƒ◊◊—ÖŒÑÕÑŒ.œ– */ + $"B739 BE00 0318 96CB CA81 C803 D176 100E" /* ∑9æ...ñÀ Å».—v.. */ + $"8900 1001 0F06 0000 0206 0C12 2951 86B8" /* â...........)QÜ∏ */ + $"D0D1 CCC9 88C8 83CA 05C8 C9CA CCBA 3FBC" /* –—Ã…à»É .»… Ã∫?º */ + $"0004 1B98 C7C5 C381 C402 C7B6 1D93 0009" /* ...ò«≈√Ń.«∂.ì.∆ */ + $"0207 0F1F 4982 ADC8 CDC7 83C5 84C6 83C5" /* ....IÇ≠»Õ«É≈Ñ∆É≈ */ + $"02C7 B842 BA00 0312 91C4 C184 C001 CB87" /* .«∏B∫...냡ѿ.Àá */ + $"9600 0801 060E 193A 75B5 C7C1 86C0 86BF" /* ñ......:uµ«¡Ü¿Üø */ + $"02C1 B536 B800 030A 7DC1 BC83 BB04 BAC1" /* .¡µ6∏..¬}¡ºÉª.∫¡ */ + $"8160 1F99 0007 040D 266E B9C2 BCBD 82BC" /* Å`.ô....&nπ¬ºΩǺ */ + $"87BB 03BC C0A8 25B6 0003 0464 BBB9 81B8" /* áª.º¿®%∂...dªπÅ∏ */ + $"80B7 04BE 8B0E 0B04 9B00 0402 0C33 96BF" /* Ä∑.æã...õ....3ñø */ + $"8FB8 02BC 9715 B500 0239 B2B5 82B4 04B2" /* è∏.ºó.µ..9≤µÇ¥.≤ */ + $"B2B4 AD25 A000 0404 1677 BAB4 87B2 01B3" /* ≤¥≠%†....w∫¥á≤.≥ */ + $"B382 B402 B873 06B3 0002 1899 B385 B002" /* ≥Ç¥.∏s.≥...ô≥Ö∞. */ + $"B764 02A2 0002 0D68 B78E B002 B1B1 43B2" /* ∑d.¢...h∑é∞.±±C≤ */ + $"0002 0671 AE85 AC02 ADA8 1CA4 0002 0B72" /* ...qÆÖ¨.≠®.§...r */ + $"B381 AB80 AA01 ACAB 84AC 03AA AD9C 1CB1" /* ≥Å´Ä™.¨´Ñ¨.™≠ú.± */ + $"0002 31A6 A780 A682 A702 AE6D 02A5 0006" /* ..1¶ßĶÇß.Æm.•.. */ + $"1692 ACA7 A8A6 A685 A800 A781 A602 AD69" /* .í¨ß®¶¶Ö®.ßŶ.≠i */ + $"04AF 0002 0A7E A681 A282 A301 A629 A600" /* .Ø..¬~¶Å¢Ç£.¶)¶. */ + $"0301 2DA1 A381 A280 A386 A202 A4A1 28AF" /* ..-°£Å¢Ä£Ü¢.§°(Ø */ + $"0001 3EA2 869E 02A3 7E04 A700 0403 55A6" /* ..>¢Üû.£~.ß...U¶ */ + $"9E9E 82A0 869E 03A0 A374 07AD 0002 097C" /* ûûdžÜû.†£t.≠..∆| */ + $"9D85 9902 9AA1 35A9 0003 1594 9B98 8899" /* ùÖô.ö°5©...îõòàô */ + $"819A 029B 9C28 AD00 012C 9986 9802 9D71" /* Åö.õú(≠..,ôÜò.ùq */ + $"05A9 0004 0178 9997 9780 9885 9781 9801" /* .©...xôóóÄòÖóÅò. */ + $"9D60 AC00 0304 6897 9184 9202 9586 18AB" /* ù`¨...hóëÑí.ïÜ.´ */ + $"0001 4599 8F92 018E 18AB 0003 178B 8F8F" /* ..Eôèí.é.´...ãèè */ + $"8490 028E 2501 AB00 020C 7E94 8590 808E" /* Ñê.é%.´...~îÖêÄé */ + $"8090 048E 8E8F 9642 AB00 0338 9089 8983" /* Äê.ééèñB´..8êââÉ */ + $"8A02 8F5D 01AD 0002 2082 9082 8B82 8A80" /* ä.è].≠.. ÇêÇãÇäÄ */ + $"8B80 8A02 8F69 04AA 0001 5D8C 8284 8086" /* ãÄä.èi.™..]åÇÑÄÜ */ + $"018C 24AE 0007 0119 618A 8D87 8686 8385" /* .å$Æ....aäçáÜÜÉÖ */ + $"8286 0287 8114 A900 020E 7982 8281 0483" /* ÇÜ.áÅ.©...yÇÇÅ.É */ + $"8385 7202 AF00 0701 0525 597C 8986 8382" /* ÉÖr.Ø....%Y|âÜÉÇ */ + $"8283 8301 892E A900 021E 827F 827E 0380" /* ÇÉÉ.â.©...Ç.Ç~.Ä */ + $"8085 4AB2 0007 0105 1232 5876 8382 8480" /* ÄÖJ≤.....2XvÉÇÑÄ */ + $"037F 7F83 4AA9 0004 3282 7A7B 7B80 7903" /* ...ÉJ©..2Çz{{Äy. */ + $"7A79 7F24 B500 0702 050F 2E5A 797F 7D81" /* zy.$µ......Zy.}Å */ + $"7A04 7B79 7F5E 03A8 0001 437E 8077 8176" /* z.{y.^.®..C~ÄwÅv */ + $"0277 700B B800 0602 0519 446B 7D79 8176" /* .wp.∏.....Dk}yÅv */ + $"0277 6B0B A800 014F 7780 7381 7201 7656" /* .wk.®..OwÄsÅr.vV */ + $"BB00 0B01 0309 2F60 7975 7373 746F 0FA8" /* ª....∆/`yussto.® */ + $"0001 5672 8170 806F 0174 36BE 0008 0205" /* ..VrÅpÄo.t6æ.... */ + $"336C 7370 6F70 17A7 0002 0659 6E81 6B80" /* 3lspop.ß...YnÅkÄ */ + $"6A01 6F1C C000 0602 155B 6F6B 6D1B A700" /* j.o.¿....[okm.ß. */ + $"0306 586A 6880 6704 6666 6762 07C2 0004" /* ..XjhÄg.ffgb.¬.. */ + $"0C57 6A6B 1CA7 0003 0655 6765 8264 0165" /* .Wjk.ß...UgeÇd.e */ + $"50C4 0003 1562 681B A700 0204 5063 8161" /* Pƒ...bh.ß...PcÅa */ + $"0360 6064 33C4 0003 0139 6718 A800 0148" /* .``d3ƒ...9g.®..H */ + $"6082 5E02 5D60 18AE 000A 0414 1E25 2D2C" /* `Ç^.]`.Æ.¬...%-, */ + $"2A25 1B10 0786 0005 161E 1310 5E12 A800" /* *%...Ü......^.®. */ + $"033E 5E59 5980 5802 5A51 01AB 0006 0B27" /* .>^YYÄX.ZQ.´...' */ + $"404E 585A 5C80 5A12 5959 5751 4940 372E" /* @NXZ\ÄZ.YYWQI@7. */ + $"2820 202A 4158 5B54 2C50 0EA8 0003 3059" /* ( *AX[T,P.®..0Y */ + $"5555 8054 0158 3CAA 0008 0B31 4F57 5655" /* UUÄT.X<™...1OWVU */ + $"5455 5580 5680 5502 5656 5780 5809 5757" /* TUUÄVÄU.VVWÄX∆WW */ + $"5656 5556 5757 4D07 A800 0122 5680 5203" /* VVUVWWM.®.."VÄR. */ + $"5151 5526 A800 0408 2B4B 5452 8151 8352" /* QQU&®...+KTRÅQÉR */ + $"8251 8052 8251 0352 5254 3FA9 0000 1581" /* ÇQÄRÇQ.RRT?©...Å */ + $"5003 4F4F 5118 A600 020B 2A45 8050 834F" /* P.OOQ.¶...*EÄPÉO */ + $"8250 834F 0150 5084 4F01 522E A900 020A" /* ÇPÉO.PPÑO.R.©..¬ */ + $"454B 814A 014C 0DA4 0003 1431 454C 824B" /* EKÅJ.L.§...1ELÇK */ + $"8D4A 824B 814A 014E 1BAA 0001 324A 8047" /* çJÇKÅJ.N.™..2JÄG */ + $"0148 43A2 0006 051E 3947 4847 4682 4885" /* .HC¢....9GHGFÇHÖ */ + $"4783 4801 4747 8348 8047 0144 0CAA 0001" /* GÉH.GGÉHÄG.D.™.. */ + $"1C48 8145 003C A000 0506 233C 4644 4480" /* .HÅE.<†...#>@,ù.. */ + $"0E2F 3F3E 3F82 4080 3E80 3F82 4080 3F80" /* ./?>?Ç@Ä>Ä?Ç@Ä?Ä */ + $"3E8B 3F01 3D0C AC00 0513 3D3B 3A3D 249C" /* >ã?.=.¨...=;:=$ú */ + $"0005 1436 3B3B 3A3A 803B 823A 8039 823B" /* ...6;;::Ä;Ç:Ä9Ç; */ + $"833A 803B 873A 013E 26AD 0005 042E 3837" /* É:Ä;á:.>&≠....87 */ + $"3920 9B00 0316 3937 3680 3780 3883 3701" /* 9 õ...976Ä7Ä8É7. */ + $"3636 8837 8336 8037 8136 0138 0FAE 0004" /* 66à7É6Ä7Å6.8.Æ.. */ + $"1536 3437 1D9A 0001 0A32 8133 8034 0135" /* .647.ö..¬2Å3Ä4.5 */ + $"3583 3480 3301 3434 8335 8B34 0136 25AF" /* 5É4Ä3.44É5ã4.6%Ø */ + $"0004 0327 3232 1D9A 0001 2732 8130 8031" /* ...'22.ö..'2Å0Ä1 */ + $"8032 9B31 0130 0DB0 0003 0E2F 2F20 9900" /* Ä2õ1.0.∞...// ô. */ + $"0111 2F88 2D80 2E88 2D82 2E87 2D01 301D" /* ../à-Ä.à-Ç.á-.0. */ + $"B200 021B 2D22 9900 0121 2B81 2A84 2B80" /* ≤...-"ô..!+Å*Ñ+Ä */ + $"2C82 2B80 2A80 2B80 2C85 2B80 2C02 2B28" /* ,Ç+Ä*Ä+Ä,Ö+Ä,.+( */ + $"09B2 0002 0624 2498 0000 0583 2784 2880" /* ∆≤...$$ò...É'Ñ(Ä */ + $"2997 2800 10B4 0002 0D26 0497 0001 0E26" /* )ó(..¥...&.ó...& */ + $"8524 8D25 8224 8325 8124 0127 18B6 0001" /* Ö$ç%Ç$É%Å$.'.∂.. */ + $"1408 9700 0114 2385 2184 2280 238B 2280" /* ..ó...#Ö!Ñ"Ä#ã"Ä */ + $"2380 2202 231C 04D2 0001 161F 851E 841F" /* #Ä".#..“....Ö.Ñ. */ + $"8020 861F 801E 821F 8020 011C 08D3 0001" /* Ä Ü.Ä.Ç.Ä ...”.. */ + $"171D 841C 881D 801E 861D 801C 811D 011C" /* ..Ñ.à.Ä.Ü.Ä.Å... */ + $"09D4 0001 151A 8819 941A 0319 1A19 0AD5" /* ∆‘....à.î.....¬’ */ + $"0001 1317 8816 8717 8018 8717 0218 1609" /* ....à.á.Ä.á....∆ */ + $"D600 0111 158B 1487 1580 1684 1501 1307" /* ÷....ã.á.Ä.Ñ.... */ + $"D700 000E 9E12 0213 0E04 D800 010A 108B" /* ◊...û.....ÿ..¬.ã */ + $"0F8F 1000 0BDA 0001 080E 950D 830E 010D" /* .è...⁄....ï.É... */ + $"07DB 0000 049B 0B01 0903 DD00 9909 0107" /* .€...õ..∆.›.ô∆.. */ + $"04DF 0098 0600 03E1 0096 03FF 00FF 00FF" /* .fl.ò...·.ñ.ˇ.ˇ.ˇ */ + $"00FF 00FF 00FF 00FF 00FF 00FF 00FF 00FF" /* .ˇ.ˇ.ˇ.ˇ.ˇ.ˇ.ˇ.ˇ */ + $"00FF 00FF 00FF 00FF 00FF 00FF 00FF 00FF" /* .ˇ.ˇ.ˇ.ˇ.ˇ.ˇ.ˇ.ˇ */ + $"00FF 00FF 00FF 00FF 00FF 00FF 00FF 00FF" /* .ˇ.ˇ.ˇ.ˇ.ˇ.ˇ.ˇ.ˇ */ + $"00FF 00FF 00FF 00FF 00FF 00FF 00FF 00FF" /* .ˇ.ˇ.ˇ.ˇ.ˇ.ˇ.ˇ.ˇ */ + $"00FF 00FF 00FF 00FF 00FF 00FF 00FF 00FF" /* .ˇ.ˇ.ˇ.ˇ.ˇ.ˇ.ˇ.ˇ */ + $"00FF 00FF 00FF 00FF 00FF 00FF 00FF 00FF" /* .ˇ.ˇ.ˇ.ˇ.ˇ.ˇ.ˇ.ˇ */ + $"00FF 00FF 00FF 00FF 00BD 0074 386D 6B00" /* .ˇ.ˇ.ˇ.ˇ.Ω.t8mk. */ + $"0040 0800 0000 0000 0000 0000 0000 0000" /* .@.............. */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0006 111F 303C 5376" /* ............0î“ÓÛÙı */ + $"F6F8 FBFD FFFF FEFE FEFE FEFE FEFE FEFE" /* ˆ¯˚˝ˇˇ˛˛˛˛˛˛˛˛˛˛ */ + $"FEFE FEFE FEFE FEFE FEFE FEFE FEFE FEFF" /* ˛˛˛˛˛˛˛˛˛˛˛˛˛˛˛ˇ */ + $"FEFB F6F1 ECEB ECEC EAE4 CA90 3D04 0000" /* ˛˚ˆÒÏÎÏÏ͉ ê=... */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 074F A8E1 F3F5 F5F5 F7FA" /* .......O®·Ûııı˜˙ */ + $"FDFE FEFE FEFE FEFE FEFE FEFE FEFE FEFE" /* ˝˛˛˛˛˛˛˛˛˛˛˛˛˛˛˛ */ + $"FEFE FEFE FEFE FEFE FEFE FEFE FEFE FEFE" /* ˛˛˛˛˛˛˛˛˛˛˛˛˛˛˛˛ */ + $"FEFE FFFD F9F3 EDEA EBEB EBE8 D8A2 4E08" /* ˛˛ˇ˝˘ÛÌÍÎÎÎËÿ¢N. */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 054D B0E8 F4F5 F5F4 F7FB FDFE" /* .....M∞ËÙııÙ˜˚˝˛ */ + $"FEFE FEFE FEFE FEFE FEFE FEFE FEFE FEFE" /* ˛˛˛˛˛˛˛˛˛˛˛˛˛˛˛˛ */ + $"FEFE FEFE FEFE FEFE FEFE FEFE FEFE FEFE" /* ˛˛˛˛˛˛˛˛˛˛˛˛˛˛˛˛ */ + $"FEFE FEFE FEFE FAF3 ECEA EAEB EAE9 DEA9" /* ˛˛˛˛˛˛˙ÛÏÍÍÎÍÈfi© */ + $"4C06 0000 0000 0000 0000 0000 0000 0000" /* L............... */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 003B A8E7 F3F6 F6F4 F7FB FDFE FEFE" /* ...;®ÁÛˆˆÙ˜˚˝˛˛˛ */ + $"FEFE FEFE FEFE FEFE FEFE FEFE FEFE FEFE" /* ˛˛˛˛˛˛˛˛˛˛˛˛˛˛˛˛ */ + $"FEFE FEFE FEFE FEFE FEFE FEFE FEFE FDFD" /* ˛˛˛˛˛˛˛˛˛˛˛˛˛˛˝˝ */ + $"FDFD FDFD FDFD FDFD F9F2 EBE9 EAEA EAEA" /* ˝˝˝˝˝˝˝˝˘ÚÎÈÍÍÍÍ */ + $"DCA1 3B00 0000 0000 0000 0000 0000 0000" /* ‹°;............. */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0020 8DE0 F4F6 F6F5 F6F9 FDFE FEFE FEFE" /* . ç‡Ùˆˆıˆ˘˝˛˛˛˛˛ */ + $"FEFE FEFE FEFE FEFE FEFE FEFE FEFE FEFE" /* ˛˛˛˛˛˛˛˛˛˛˛˛˛˛˛˛ */ + $"FEFE FEFE FEFE FEFD FDFD FDFD FDFD FDFD" /* ˛˛˛˛˛˛˛˝˝˝˝˝˝˝˝˝ */ + $"FDFD FDFD FDFD FDFD FDFD F7EE E9EA EAE9" /* ˝˝˝˝˝˝˝˝˝˝˜ÓÈÍÍÈ */ + $"EAE9 D589 2000 0000 0000 0000 0000 0000" /* ÍÈ’â ........... */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0004" /* ................ */ + $"5CCB F4F6 F6F5 F5F7 FCFE FEFE FEFE FEFE" /* \ÀÙˆˆıı˜¸˛˛˛˛˛˛˛ */ + $"FEFE FEFE FEFE FEFE FEFE FEFE FEFE FEFE" /* ˛˛˛˛˛˛˛˛˛˛˛˛˛˛˛˛ */ + $"FEFD FDFD FDFD FDFD FDFD FDFD FDFD FDFD" /* ˛˝˝˝˝˝˝˝˝˝˝˝˝˝˝˝ */ + $"FDFD FDFD FDFD FDFD FDFD FDFA F3EA EAE9" /* ˝˝˝˝˝˝˝˝˝˝˝˙ÛÍÍÈ */ + $"E9E9 E9E6 C35B 0500 0000 0000 0000 0000" /* ÈÈÈÊ√[.......... */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 239F" /* ..............#ü */ + $"EBF5 F6F5 F5F5 F9FE FEFE FEFE FEFE FEFE" /* Îıˆııı˘˛˛˛˛˛˛˛˛˛ */ + $"FEFE FFFE FEFE FEFF FFFE FEFE FDFD FDFD" /* ˛˛ˇ˛˛˛˛ˇˇ˛˛˛˝˝˝˝ */ + $"FDFD FDFD FDFD FDFD FDFD FDFD FDFD FDFD" /* ˝˝˝˝˝˝˝˝˝˝˝˝˝˝˝˝ */ + $"FDFD FDFD FDFD FDFC FCFC FCFC FCF6 ECE9" /* ˝˝˝˝˝˝˝¸¸¸¸¸¸ˆÏÈ */ + $"E9E9 E9E9 E9DE 9923 0000 0000 0000 0000" /* ÈÈÈÈÈfiô#........ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0052 CBF5" /* .............RÀı */ + $"F6F6 F5F5 F6FA FEFE FEFE FEFE FEFE FEFF" /* ˆˆııˆ˙˛˛˛˛˛˛˛˛˛ˇ */ + $"FFFF FFFF FFFF FFFF FFFF FDFD FDFE FDFD" /* ˇˇˇˇˇˇˇˇˇˇ˝˝˝˛˝˝ */ + $"FDFD FDFD FDFD FDFD FDFD FDFD FDFD FDFD" /* ˝˝˝˝˝˝˝˝˝˝˝˝˝˝˝˝ */ + $"FDFD FDFD FCFC FCFC FCFC FCFC FCFD F8EF" /* ˝˝˝˝¸¸¸¸¸¸¸¸¸˝¯Ô */ + $"E9E9 E9E9 E8E9 E7C3 5100 0000 0000 0000" /* ÈÈÈÈËÈÁ√Q....... */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 000B 81E6 F5F6" /* ............ÅÊıˆ */ + $"F5F5 F5F6 FBFE FEFE FEFE FEFE FEFE FFFF" /* ıııˆ˚˛˛˛˛˛˛˛˛˛ˇˇ */ + $"FFFF FFFF FFFF FFFF FFFF FFFE FEFF FFFF" /* ˇˇˇˇˇˇˇˇˇˇˇ˛˛ˇˇˇ */ + $"FEFE FDFD FDFD FDFD FDFD FDFD FDFD FDFC" /* ˛˛˝˝˝˝˝˝˝˝˝˝˝˝˝¸ */ + $"FCFC FCFC FCFC FCFC FCFC FCFC FCFC FCFA" /* ¸¸¸¸¸¸¸¸¸¸¸¸¸¸¸˙ */ + $"F0E9 E9E9 E8E8 E9E9 DC7E 0C00 0000 0000" /* ÈÈÈËËÈÈ‹~...... */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 20A7 F1F6 F6F5" /* .......... ßÒˆˆı */ + $"F5F5 F6FB FDFD FDFD FDFD FDFE FFFF FFFF" /* ııˆ˚˝˝˝˝˝˝˝˛ˇˇˇˇ */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* ˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇ */ + $"FFFF FFFF FEFE FDFD FDFD FDFD FCFC FCFC" /* ˇˇˇˇ˛˛˝˝˝˝˝˝¸¸¸¸ */ + $"FCFC FCFC FCFC FCFC FCFC FCFC FCFB FBFB" /* ¸¸¸¸¸¸¸¸¸¸¸¸¸˚˚˚ */ + $"FAF1 E9E9 E9E8 E8E8 E8E4 A120 0000 0000" /* ˙ÒÈÈÈËËËˉ° .... */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0034 C4F5 F5F5 F5F5" /* .........4ƒııııı */ + $"F5F7 FBFD FDFD FDFD FDFD FDFD FFFF FFFF" /* ı˜˚˝˝˝˝˝˝˝˝˝ˇˇˇˇ */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* ˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇ */ + $"FFFF FFFF FFFF FFFE FEFD FCFC FCFC FCFC" /* ˇˇˇˇˇˇˇ˛˛˝¸¸¸¸¸¸ */ + $"FCFC FCFC FCFC FCFC FCFC FBFB FBFB FBFB" /* ¸¸¸¸¸¸¸¸¸¸˚˚˚˚˚˚ */ + $"FBFA F1E8 E9E9 E8E8 E8E9 E8BB 3300 0000" /* ˚˙ÒËÈÈËËËÈ˪3... */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 49D4 F6F5 F4F5 F5F5" /* ........I‘ˆıÙııı */ + $"F6FB FDFD FDFD FDFD FDFD FDFD FDFF FFFF" /* ˆ˚˝˝˝˝˝˝˝˝˝˝˝ˇˇˇ */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* ˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇ */ + $"FFFF FFFF FFFF FFFF FFFF FEFD FCFC FCFC" /* ˇˇˇˇˇˇˇˇˇˇ˛˝¸¸¸¸ */ + $"FCFC FCFC FCFC FCFB FBFB FBFB FBFB FBFB" /* ¸¸¸¸¸¸¸˚˚˚˚˚˚˚˚˚ */ + $"FBFB FBEF E8E9 E9E8 E8E7 E8E9 CB47 0000" /* ˚˚˚ÔËÈÈËËÁËÈÀG.. */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0055 E0F6 F5F4 F5F5 F5F5" /* .......U‡ˆıÙıııı */ + $"FAFD FDFD FDFD FDFD FDFD FDFE FEFE FFFF" /* ˙˝˝˝˝˝˝˝˝˝˝˛˛˛ˇˇ */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* ˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇ */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFD FCFC" /* ˇˇˇˇˇˇˇˇˇˇˇˇˇ˝¸¸ */ + $"FCFC FCFB FBFB FBFB FBFB FBFB FBFB FBFB" /* ¸¸¸˚˚˚˚˚˚˚˚˚˚˚˚˚ */ + $"FBFB FAF9 EEE8 E9E8 E8E7 E7E8 E9D5 5400" /* ˚˚˙˘ÓËÈËËÁÁËÈ’T. */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 5EE4 F7F5 F4F4 F5F5 F5F9" /* ......^‰˜ıÙÙııı˘ */ + $"FDFD FDFD FDFD FDFD FDFD FDFF FFFF FFFF" /* ˝˝˝˝˝˝˝˝˝˝˝ˇˇˇˇˇ */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* ˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇ */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FEFD" /* ˇˇˇˇˇˇˇˇˇˇˇˇˇˇ˛˝ */ + $"FCFC FCFB FBFB FBFB FBFB FBFB FBFB FBFA" /* ¸¸¸˚˚˚˚˚˚˚˚˚˚˚˚˙ */ + $"FAFA FAFA F7EC E9E9 E8E8 E7E7 E8E8 D85C" /* ˙˙˙˙˜ÏÈÈËËÁÁËËÿ\ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 005E E6F5 F4F4 F4F4 F5F5 F7FD" /* .....^ÊıÙÙÙÙıı˜˝ */ + $"FDFD FDFD FDFD FDFD FDFD FFFF FFFF FFFF" /* ˝˝˝˝˝˝˝˝˝˝ˇˇˇˇˇˇ */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* ˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇ */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* ˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇ */ + $"FDFB FBFB FBFB FBFB FBFB FBFB FBFA FAFA" /* ˝˚˚˚˚˚˚˚˚˚˚˚˚˙˙˙ */ + $"FAFA FAFA FBF5 E9E9 E9E8 E8E7 E7E8 E8DC" /* ˙˙˙˙˚ıÈÈÈËËÁÁËË‹ */ + $"5B00 0000 0000 0000 0000 0000 0000 0000" /* [............... */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 56E5 F6F3 F4F4 F4F5 F5F6 FCFD" /* ....VˆÛÙÙÙııˆ¸˝ */ + $"FDFD FDFD FDFD FDFD FDFE FFFF FFFF FFFF" /* ˝˝˝˝˝˝˝˝˝˛ˇˇˇˇˇˇ */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* ˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇ */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* ˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇ */ + $"FFFD FBFB FBFB FBFB FBFB FBFA FAFA FAFA" /* ˇ˝˚˚˚˚˚˚˚˚˚˙˙˙˙˙ */ + $"FAFA FAFA FAF9 F0E8 E9E8 E8E7 E7E7 E8E8" /* ˙˙˙˙˙˘ËÈËËÁÁÁËË */ + $"DA54 0000 0000 0000 0000 0000 0000 0000" /* ⁄T.............. */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0048 E1F6 F3F4 F4F4 F4F5 F5F9 FCFD" /* ...H·ˆÛÙÙÙÙıı˘¸˝ */ + $"FDFD FDFD FDFD FDFD FDFF FFFF FFFF FFFF" /* ˝˝˝˝˝˝˝˝˝ˇˇˇˇˇˇˇ */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* ˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇ */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* ˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇ */ + $"FFFF FCFB FBFB FBFB FAFA FAFA FAFA FAFA" /* ˇˇ¸˚˚˚˚˚˙˙˙˙˙˙˙˙ */ + $"FAFA FAFA F9F9 F8ED E9E9 E8E8 E7E7 E7E8" /* ˙˙˙˙˘˘¯ÌÈÈËËÁÁÁË */ + $"E8D6 4600 0000 0000 0000 0000 0000 0000" /* Ë÷F............. */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 33D6 F7F3 F3F4 F4F4 F4F5 F7FC FCFC" /* ..3÷˜ÛÛÙÙÙÙı˜¸¸¸ */ + $"FCFC FCFD FDFD FDFD FEFF FFFF FFFF FFFF" /* ¸¸¸˝˝˝˝˝˛ˇˇˇˇˇˇˇ */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* ˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇ */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* ˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇ */ + $"FFFF FFFB FBFB FAFA FAFA FAFA FAFA FAFA" /* ˇˇˇ˚˚˚˙˙˙˙˙˙˙˙˙˙ */ + $"FAF9 F9F9 F9F9 F9F4 E9E9 E8E8 E8E7 E7E7" /* ˙˘˘˘˘˘˘ÙÈÈËËËÁÁÁ */ + $"E7E8 CD32 0000 0000 0000 0000 0000 0000" /* ÁËÕ2............ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"001F C5F6 F3F3 F3F4 F4F4 F4F5 FBFC FCFC" /* ..≈ˆÛÛÛÙÙÙÙı˚¸¸¸ */ + $"FCFC FDFD FDFD FDFD FEFF FFFF FFFF FFFF" /* ¸¸˝˝˝˝˝˝˛ˇˇˇˇˇˇˇ */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* ˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇ */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* ˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇ */ + $"FFFF FFFE FAFA FAFA FAFA FAFA FAFA FAF9" /* ˇˇˇ˛˙˙˙˙˙˙˙˙˙˙˙˘ */ + $"F9F9 F9F9 F9F9 F9F8 EEE8 E9E8 E8E7 E7E7" /* ˘˘˘˘˘˘˘¯ÓËÈËËÁÁÁ */ + $"E7E7 EABD 1F00 0000 0000 0000 0000 0000" /* ÁÁÍΩ............ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0BA9 F7F3 F3F3 F3F4 F4F4 F4F8 FCFC FCFC" /* .©˜ÛÛÛÛÙÙÙÙ¯¸¸¸¸ */ + $"FCFC FCFC FCFC FDFD FFFF FFFF FFFF FFFF" /* ¸¸¸¸¸¸˝˝ˇˇˇˇˇˇˇˇ */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* ˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇ */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* ˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇ */ + $"FFFF FFFF FCFA FAFA FAFA FAFA FAF9 F9F9" /* ˇˇˇˇ¸˙˙˙˙˙˙˙˙˘˘˘ */ + $"F9F9 F9F9 F9F9 F8F8 F4EA E9E9 E8E8 E7E7" /* ˘˘˘˘˘˘¯¯ÙÍÈÈËËÁÁ */ + $"E7E6 E7EB A20B 0000 0000 0000 0000 0000" /* ÁÊÁ΢........... */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"81F4 F3F2 F3F3 F3F4 F4F4 F5FB FCFC FCFC" /* ÅÙÛÚÛÛÛÙÙÙı˚¸¸¸¸ */ + $"FCFC FCFC FCFC FDFE FFFF FFFF FFFF FFFF" /* ¸¸¸¸¸¸˝˛ˇˇˇˇˇˇˇˇ */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* ˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇ */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* ˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇ */ + $"FFFF FFFF FEFA FAFA FAFA FAF9 F9F9 F9F9" /* ˇˇˇˇ˛˙˙˙˙˙˙˘˘˘˘˘ */ + $"F9F9 F9F9 F8F8 F8F8 F8EE E8E9 E8E8 E7E7" /* ˘˘˘˘¯¯¯¯¯ÓËÈËËÁÁ */ + $"E7E7 E6E7 E87C 0100 0000 0000 0000 0000" /* ÁÁÊÁË|.......... */ + $"0000 0000 0000 0000 0000 0000 0000 0050" /* ...............P */ + $"EBF4 F2F2 F3F3 F3F4 F4F4 F7FC FCFC FCFC" /* ÎÙÚÚÛÛÛÙÙÙ˜¸¸¸¸¸ */ + $"FCFC FCFC FCFD FDFF FFFF FFFF FFFF FFFF" /* ¸¸¸¸¸˝˝ˇˇˇˇˇˇˇˇˇ */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* ˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇ */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* ˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇ */ + $"FFFF FFFF FFFB FAFA FAF9 F9F9 F9F9 F9F9" /* ˇˇˇˇˇ˚˙˙˙˘˘˘˘˘˘˘ */ + $"F9F9 F8F8 F8F8 F8F8 F8F3 E9E9 E9E8 E8E7" /* ˘˘¯¯¯¯¯¯¯ÛÈÈÈËËÁ */ + $"E7E7 E6E6 E9E0 4D00 0000 0000 0000 0000" /* ÁÁÊÊȇM......... */ + $"0000 0000 0000 0000 0000 0000 0000 24D8" /* ..............$ÿ */ + $"F5F2 F2F2 F3F3 F3F4 F4F4 FAFB FBFC FCFC" /* ıÚÚÚÛÛÛÙÙÙ˙˚˚¸¸¸ */ + $"FCFC FCFC FCFD FFFF FFFF FFFF FFFF FFFF" /* ¸¸¸¸¸˝ˇˇˇˇˇˇˇˇˇˇ */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* ˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇ */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* ˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇ */ + $"FFFF FFFF FFFC FAFA FAF9 F9F9 F9F9 F9F9" /* ˇˇˇˇˇ¸˙˙˙˘˘˘˘˘˘˘ */ + $"F9F9 F8F8 F8F8 F8F8 F7F7 EDE9 E9E8 E8E8" /* ˘˘¯¯¯¯¯¯˜˜ÌÈÈËËË */ + $"E7E7 E7E6 E6E9 CF23 0000 0000 0000 0000" /* ÁÁÁÊÊÈœ#........ */ + $"0000 0000 0000 0000 0000 0000 0005 AAF9" /* ..............™˘ */ + $"F1F2 F2F2 F3F3 F3F4 F4F5 FBFB FBFC FCFC" /* ÒÚÚÚÛÛÛÙÙı˚˚˚¸¸¸ */ + $"FCFC FCFC FCFE FFFF FFFF FFFF FFFF FFFF" /* ¸¸¸¸¸˛ˇˇˇˇˇˇˇˇˇˇ */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* ˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇ */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* ˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇ */ + $"FFFF FFFF FFFE FBF9 F9F9 F9F9 F9F9 F9F9" /* ˇˇˇˇˇ˛˚˘˘˘˘˘˘˘˘˘ */ + $"F8F8 F8F8 F8F8 F8F8 F7F8 F0E9 E9E9 E8E8" /* ¯¯¯¯¯¯¯¯˜¯ÈÈÈËË */ + $"E8E7 E7E7 E6E6 EDA3 0500 0000 0000 0000" /* ËÁÁÁÊÊÌ£........ */ + $"0000 0000 0000 0000 0000 0000 0060 F6F1" /* .............`ˆÒ */ + $"F1F2 F2F2 F3F3 F3F4 F4F7 FBFB FBFC FCFC" /* ÒÚÚÚÛÛÛÙÙ˜˚˚˚¸¸¸ */ + $"FCFC FCFC FDFF FFFF FFFF FFFF FFFF FFFF" /* ¸¸¸¸˝ˇˇˇˇˇˇˇˇˇˇˇ */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* ˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇ */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* ˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇ */ + $"FFFF FFFF FFFF FEFA F9F9 F9F9 F9F9 F8F8" /* ˇˇˇˇˇˇ˛˙˘˘˘˘˘˘¯¯ */ + $"F8F8 F8F8 F8F8 F7F7 F7F7 F5EA E9E9 E8E8" /* ¯¯¯¯¯¯˜˜˜˜ıÍÈÈËË */ + $"E8E7 E7E7 E6E6 E6EA 5D00 0000 0000 0000" /* ËÁÁÁÊÊÊÍ]....... */ + $"0000 0000 0000 0000 0000 0000 1FD8 F4F1" /* .............ÿÙÒ */ + $"F1F2 F2F2 F3F3 F3F4 F4F9 FBFB FBFB FBFB" /* ÒÚÚÚÛÛÛÙÙ˘˚˚˚˚˚˚ */ + $"FCFC FCFC FEFF FFFF FFFF FFFF FFFF FFFF" /* ¸¸¸¸˛ˇˇˇˇˇˇˇˇˇˇˇ */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* ˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇ */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* ˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇ */ + $"FFFF FFFF FFFF FFFE FBF9 F9F9 F9F9 F8F8" /* ˇˇˇˇˇˇˇ˛˚˘˘˘˘˘¯¯ */ + $"F8F8 F8F8 F7F7 F7F7 F7F7 F6EC E9E9 E9E8" /* ¯¯¯¯˜˜˜˜˜˜ˆÏÈÈÈË */ + $"E8E8 E7E7 E7E6 E6E9 D01F 0000 0000 0000" /* ËËÁÁÁÊÊÈ–....... */ + $"0000 0000 0000 0000 0000 0000 96F9 F0F1" /* ............ñ˘Ò */ + $"F1F2 F2F2 F3F3 F3F4 F5FA FBFB FBFB FBFB" /* ÒÚÚÚÛÛÛÙı˙˚˚˚˚˚˚ */ + $"FCFC FCFC FFFF FFFF FFFF FFFF FFFF FFFF" /* ¸¸¸¸ˇˇˇˇˇˇˇˇˇˇˇˇ */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* ˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇ */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* ˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇ */ + $"FFFF FFFF FFFF FFFF FFFD FBF9 F8F8 F8F8" /* ˇˇˇˇˇˇˇˇˇ˝˚˘¯¯¯¯ */ + $"F8F8 F7F8 F7F7 F7F7 F7F7 F7EF E9E9 E9E9" /* ¯¯˜¯˜˜˜˜˜˜˜ÔÈÈÈÈ */ + $"E8E8 E7E7 E7E6 E6E6 ED91 0000 0000 0000" /* ËËÁÁÁÊÊÊÌë...... */ + $"0000 0000 0000 0000 0000 003C ECF1 F0F1" /* ...........<ÏÒÒ */ + $"F1F2 F2F2 F3F3 F3F3 F6FA FBFB FBFB FBFB" /* ÒÚÚÚÛÛÛÛˆ˙˚˚˚˚˚˚ */ + $"FCFC FCFD FFFF FFFF FFFF FFFF FFFF FFFF" /* ¸¸¸˝ˇˇˇˇˇˇˇˇˇˇˇˇ */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* ˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇ */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* ˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇ */ + $"FFFF FFFF FFFF FFFF FFFF FFFE FCFA F8F8" /* ˇˇˇˇˇˇˇˇˇˇˇ˛¸˙¯¯ */ + $"F8F8 F7F7 F7F7 F7F7 F6F6 F6F1 EAE9 E9E9" /* ¯¯˜˜˜˜˜˜ˆˆˆÒÍÈÈÈ */ + $"E8E8 E8E7 E7E7 E6E6 E6E2 3C00 0000 0000" /* ËËËÁÁÁÊÊÊ‚<..... */ + $"0000 0000 0000 0000 0000 06B4 F7F0 F0F1" /* ...........¥˜Ò */ + $"F1F1 F2F2 F2F3 F3F3 F7FA FBFB FBFB FBFB" /* ÒÒÚÚÚÛÛÛ˜˙˚˚˚˚˚˚ */ + $"FBFB FBFE FFFF FFFF FFFF FFFF FFFF FFFF" /* ˚˚˚˛ˇˇˇˇˇˇˇˇˇˇˇˇ */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* ˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇ */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* ˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇ */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FEFC" /* ˇˇˇˇˇˇˇˇˇˇˇˇˇˇ˛¸ */ + $"F9F7 F7F7 F7F7 F7F7 F6F6 F6F4 EAEA E9E9" /* ˘˜˜˜˜˜˜˜ˆˆˆÙÍÍÈÈ */ + $"E9E8 E8E8 E7E7 E6E6 E6EB AD07 0000 0000" /* ÈËËËÁÁÊÊÊÎ≠..... */ + $"0000 0000 0000 0000 0000 50F2 F0F0 F0F1" /* ..........PÚÒ */ + $"F1F1 F2F2 F2F3 F3F3 F8FA FAFA FAFB FBFB" /* ÒÒÚÚÚÛÛÛ¯˙˙˙˙˚˚˚ */ + $"FBFB FBFF FFFF FFFF FFFF FFFF FFFF FFFF" /* ˚˚˚ˇˇˇˇˇˇˇˇˇˇˇˇˇ */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* ˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇ */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* ˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇ */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* ˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇ */ + $"FFFD FAF8 F7F7 F6F6 F6F6 F6F5 EBEA E9E9" /* ˇ˝˙¯˜˜ˆˆˆˆˆıÎÍÈÈ */ + $"E9E8 E8E8 E7E7 E7E6 E6E6 E94E 0000 0000" /* ÈËËËÁÁÁÊÊÊÈN.... */ + $"0000 0000 0000 0000 0009 BCF5 F0F0 F0F1" /* .........∆ºıÒ */ + $"F1F1 F2F2 F2F3 F3F3 F8FA FAFA FAFB FBFB" /* ÒÒÚÚÚÛÛÛ¯˙˙˙˙˚˚˚ */ + $"FBFB FCFF FFFF FFFF FFFF FFFF FFFF FFFF" /* ˚˚¸ˇˇˇˇˇˇˇˇˇˇˇˇˇ */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* ˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇ */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* ˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇ */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* ˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇ */ + $"FFFF FFFE FBF8 F6F6 F6F6 F6F6 ECEA EAE9" /* ˇˇˇ˛˚¯ˆˆˆˆˆˆÏÍÍÈ */ + $"E9E9 E8E8 E7E7 E7E6 E6E6 EBB6 0900 0000" /* ÈÈËËÁÁÁÊÊÊÎ∂∆... */ + $"0000 0000 0000 0000 0052 F4F0 EFF0 F0F1" /* .........RÙÔÒ */ + $"F1F1 F2F2 F2F3 F3F3 F9FA FAFA FAFA FBFB" /* ÒÒÚÚÚÛÛÛ˘˙˙˙˙˙˚˚ */ + $"FBFB FDFF FFFF FFFF FFFF FFFF FFFF FFFF" /* ˚˚˝ˇˇˇˇˇˇˇˇˇˇˇˇˇ */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* ˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇ */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* ˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇ */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* ˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇ */ + $"FFFF FFFF FFFE FAF6 F6F6 F5F5 EDEA EAE9" /* ˇˇˇˇˇ˛˙ˆˆˆııÌÍÍÈ */ + $"E9E9 E8E8 E8E7 E7E7 E6E6 E6EA 5100 0000" /* ÈÈËËËÁÁÁÊÊÊÍQ... */ + $"0000 0000 0000 0000 05B6 F5EF EFF0 F0F0" /* .........∂ıÔÔ */ + $"F1F1 F2F2 F2F3 F3F3 F8F9 F9FA FAFA FAFA" /* ÒÒÚÚÚÛÛÛ¯˘˘˙˙˙˙˙ */ + $"FAFB FEFF FFFF FFFF FFFF FFFF FFFF FFFF" /* ˙˚˛ˇˇˇˇˇˇˇˇˇˇˇˇˇ */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* ˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇ */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* ˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇ */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* ˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇ */ + $"FFFF FFFF FFFF FFFD F7F5 F5F5 EEEA EAEA" /* ˇˇˇˇˇˇˇ˝˜ıııÓÍÍÍ */ + $"E9E9 E9E8 E8E7 E7E7 E6E6 E6EB B005 0000" /* ÈÈÈËËÁÁÁÊÊÊÎ∞... */ + $"0000 0000 0000 0000 40EE F0EF EFF0 F0F0" /* ........@ÓÔÔ */ + $"F1F1 F1F2 F2F2 F3F3 F8F9 F9FA FAFA FAFA" /* ÒÒÒÚÚÚÛÛ¯˘˘˙˙˙˙˙ */ + $"FAFB FEFF FFFF FFFF FFFF FFFF FFFF FFFF" /* ˙˚˛ˇˇˇˇˇˇˇˇˇˇˇˇˇ */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* ˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇ */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* ˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇ */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* ˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇ */ + $"FFFF FFFF FFFF FFFF FEF6 F5F5 EEEA EAEA" /* ˇˇˇˇˇˇˇˇ˛ˆııÓÍÍÍ */ + $"E9E9 E9E8 E8E8 E7E7 E7E6 E6E6 E63E 0000" /* ÈÈÈËËËÁÁÁÊÊÊÊ>.. */ + $"0000 0000 0000 0000 9FF6 EEEF EFF0 F0F0" /* ........üˆÓÔÔ */ + $"F1F1 F1F2 F2F2 F3F3 F8F9 F9FA FAFA FAFA" /* ÒÒÒÚÚÚÛÛ¯˘˘˙˙˙˙˙ */ + $"FAFC FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* ˙¸ˇˇˇˇˇˇˇˇˇˇˇˇˇˇ */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* ˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇ */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* ˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇ */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* ˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇ */ + $"FFFF FFFF FFFF FFFF FFFD F5F5 EEEB EAEA" /* ˇˇˇˇˇˇˇˇˇ˝ııÓÎÍÍ */ + $"EAE9 E9E9 E8E8 E7E7 E7E6 E6E6 ED9A 0000" /* ÍÈÈÈËËÁÁÁÊÊÊÌö.. */ + $"0000 0000 0000 0021 E1F0 EEEF EFEF F0F0" /* .......!·ÓÔÔÔ */ + $"F0F1 F1F2 F2F2 F3F3 F8F9 F9F9 FAFA FAFA" /* ÒÒÚÚÚÛÛ¯˘˘˘˙˙˙˙ */ + $"FAFD FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* ˙˝ˇˇˇˇˇˇˇˇˇˇˇˇˇˇ */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* ˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇ */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* ˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇ */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* ˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇ */ + $"FFFF FFFF FFFF FFFF FFFF F9F5 EEEB EBEA" /* ˇˇˇˇˇˇˇˇˇˇ˘ıÓÎÎÍ */ + $"EAE9 E9E9 E8E8 E8E7 E7E6 E6E6 E7DA 2100" /* ÍÈÈÈËËËÁÁÊÊÊÁ⁄!. */ + $"0000 0000 0000 0071 F6EF EEEF EFEF F0F0" /* .......qˆÔÓÔÔÔ */ + $"F0F1 F1F1 F2F2 F3F3 F7F9 F9F9 F9F9 F9FA" /* ÒÒÒÚÚÛÛ˜˘˘˘˘˘˘˙ */ + $"FAFD FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* ˙˝ˇˇˇˇˇˇˇˇˇˇˇˇˇˇ */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* ˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇ */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* ˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇ */ + $"FFFF FFFE FDFD FCFB FBFB FBFC FDFE FFFF" /* ˇˇˇ˛˝˝¸˚˚˚˚¸˝˛ˇˇ */ + $"FFFF FFFF FFFF FFFC FBFC FDF4 EDEB EBEA" /* ˇˇˇˇˇˇˇ¸˚¸˝ÙÌÎÎÍ */ + $"EAEA E9E9 E9E8 E8E7 E7E7 E6E6 E6EE 6E00" /* ÍÍÈÈÈËËÁÁÁÊÊÊÓn. */ + $"0000 0000 0000 07C0 F2EE EEEE EFEF F0F0" /* .......¿ÚÓÓÓÔÔ */ + $"F0F1 F1F1 F2F2 F2F3 F7F9 F9F9 F9F9 F9FA" /* ÒÒÒÚÚÚÛ˜˘˘˘˘˘˘˙ */ + $"FAFE FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* ˙˛ˇˇˇˇˇˇˇˇˇˇˇˇˇˇ */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* ˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇ */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* ˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇ */ + $"FEFC FAF9 F9F9 F9F8 F8F8 F7F8 F7F7 F8F8" /* ˛¸˙˘˘˘˘¯¯¯˜¯˜˜¯¯ */ + $"F9F9 FAFB FBF9 F7F5 F5F5 F9F5 EDEB EBEB" /* ˘˘˙˚˚˘˜ııı˘ıÌÎÎÎ */ + $"EAEA E9E9 E9E8 E8E8 E7E7 E7E6 E6EA BB07" /* ÍÍÈÈÈËËËÁÁÁÊÊͪ. */ + $"0000 0000 0000 34EC EFEE EEEE EFEF F0F0" /* ......4ÏÔÓÓÓÔÔ */ + $"F0F1 F1F1 F2F2 F2F3 F6F9 F9F9 F9F9 F9FA" /* ÒÒÒÚÚÚÛˆ˘˘˘˘˘˘˙ */ + $"FBFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* ˚ˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇ */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* ˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇ */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FEFC" /* ˇˇˇˇˇˇˇˇˇˇˇˇˇˇ˛¸ */ + $"FAFA F9F9 F9F9 F9F8 F8F8 F7F7 F7F7 F7F7" /* ˙˙˘˘˘˘˘¯¯¯˜˜˜˜˜˜ */ + $"F6F6 F6F5 F5F5 F5F5 F4F4 F4F3 EDEB EBEB" /* ˆˆˆıııııÙÙÙÛÌÎÎÎ */ + $"EAEA EAE9 E9E8 E8E8 E7E7 E7E6 E6E6 E333" /* ÍÍÍÈÈËËËÁÁÁÊÊÊ„3 */ + $"0000 0000 0000 7CF6 EDED EEEE EFEF EFF0" /* ......|ˆÌÌÓÓÔÔÔ */ + $"F0F0 F1F1 F2F2 F2F2 F5F8 F8F8 F8F9 F9F9" /* ÒÒÚÚÚÚı¯¯¯¯˘˘˘ */ + $"FCFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* ¸ˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇ */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* ˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇ */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FEFC FAFA" /* ˇˇˇˇˇˇˇˇˇˇˇˇ˛¸˙˙ */ + $"FAFA F9F9 F9F8 F8F8 F8F8 F8F7 F7F7 F7F7" /* ˙˙˘˘˘¯¯¯¯¯¯˜˜˜˜˜ */ + $"F6F6 F6F5 F5F5 F5F5 F4F4 F4F2 ECEC EBEB" /* ˆˆˆıııııÙÙÙÚÏÏÎÎ */ + $"EAEA EAE9 E9E9 E8E8 E8E7 E7E6 E6E6 EF7B" /* ÍÍÍÈÈÈËËËÁÁÊÊÊÔ{ */ + $"0000 0000 0006 BFF2 EDED EEEE EEEF EFF0" /* ......øÚÌÌÓÓÓÔÔ */ + $"F0F0 F1F1 F1F2 F2F2 F4F8 F8F8 F8F9 F9F9" /* ÒÒÒÚÚÚÙ¯¯¯¯˘˘˘ */ + $"FDFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* ˝ˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇ */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* ˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇ */ + $"FFFF FFFF FFFF FFFF FFFF FEFC FBFA FAFA" /* ˇˇˇˇˇˇˇˇˇˇ˛¸˚˙˙˙ */ + $"F9F9 F9F9 F9F9 F8F8 F8F8 F8F7 F7F7 F6F6" /* ˘˘˘˘˘˘¯¯¯¯¯˜˜˜ˆˆ */ + $"F6F6 F6F5 F5F5 F5F5 F5F4 F4F1 ECEC EBEB" /* ˆˆˆııııııÙÙÒÏÏÎÎ */ + $"EBEA EAEA E9E9 E8E8 E8E7 E7E7 E6E6 EABA" /* ÎÍÍÍÈÈËËËÁÁÁÊÊÍ∫ */ + $"0600 0000 0029 E6EE EDED EEEE EEEF EFF0" /* .....)ÊÓÌÌÓÓÓÔÔ */ + $"F0F0 F1F1 F1F2 F2F2 F3F7 F7F8 F8F9 F9F9" /* ÒÒÒÚÚÚÛ˜˜¯¯˘˘˘ */ + $"FEFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* ˛ˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇ */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* ˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇ */ + $"FFFF FFFF FFFF FFFF FEFC FBFB FBFB FAFA" /* ˇˇˇˇˇˇˇˇ˛¸˚˚˚˚˙˙ */ + $"FAF9 F9F9 F9F9 F8F8 F8F7 F7F7 F7F7 F6F6" /* ˙˘˘˘˘˘¯¯¯˜˜˜˜˜ˆˆ */ + $"F6F6 F6F6 F5F5 F4F4 F4F4 F4F0 ECEC ECEB" /* ˆˆˆˆııÙÙÙÙÙÏÏÏÎ */ + $"EBEA EAEA E9E9 E9E8 E8E7 E7E7 E6E6 E7DF" /* ÎÍÍÍÈÈÈËËÁÁÁÊÊÁfl */ + $"2800 0000 0063 F5EC EDED EDEE EEEE EFEF" /* (....cıÏÌÌÌÓÓÓÔÔ */ + $"F0F0 F0F1 F1F1 F2F2 F3F6 F7F8 F8F8 F9F9" /* ÒÒÒÚÚÛˆ˜¯¯¯˘˘ */ + $"FEFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* ˛ˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇ */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* ˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇ */ + $"FFFF FFFF FFFF FDFC FCFB FBFB FAFA FAFA" /* ˇˇˇˇˇˇ˝¸¸˚˚˚˙˙˙˙ */ + $"FAF9 F9F9 F9F9 F9F8 F8F7 F7F7 F7F7 F7F6" /* ˙˘˘˘˘˘˘¯¯˜˜˜˜˜˜ˆ */ + $"F6F6 F5F5 F5F5 F5F4 F4F4 F3EF ECEC ECEB" /* ˆˆıııııÙÙÙÛÔÏÏÏÎ */ + $"EBEB EAEA E9E9 E9E8 E8E8 E7E7 E7E6 E6EF" /* ÎÎÍÍÈÈÈËËËÁÁÁÊÊÔ */ + $"6000 0000 009E F4EC EDED EDEE EEEE EFEF" /* `....ûÙÏÌÌÌÓÓÓÔÔ */ + $"F0F0 F0F1 F1F1 F2F2 F2F5 F7F8 F8F8 F8F9" /* ÒÒÒÚÚÚı˜¯¯¯¯˘ */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* ˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇ */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* ˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇ */ + $"FFFF FFFF FDFC FCFC FCFB FBFB FAFA FAFA" /* ˇˇˇˇ˝¸¸¸¸˚˚˚˙˙˙˙ */ + $"FAFA F9F9 F8F8 F8F8 F8F8 F7F7 F6F6 F6F6" /* ˙˙˘˘¯¯¯¯¯¯˜˜ˆˆˆˆ */ + $"F6F6 F5F5 F5F4 F4F4 F4F4 F2ED EDEC ECEB" /* ˆˆıııÙÙÙÙÙÚÌÌÏÏÎ */ + $"EBEB EAEA EAE9 E9E9 E8E8 E7E7 E7E6 E6EE" /* ÎÎÍÍÍÈÈÈËËÁÁÁÊÊÓ */ + $"9B00 0000 0BCB F0EC ECED EDEE EEEE EFEF" /* õ....ÀÏÏÌÌÓÓÓÔÔ */ + $"EFF0 F0F0 F1F1 F2F2 F2F4 F7F7 F8F8 F8F9" /* ÔÒÒÚÚÚÙ˜˜¯¯¯˘ */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* ˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇ */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* ˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇ */ + $"FFFF FEFD FCFC FCFC FCFC FBFB FBFA FAFA" /* ˇˇ˛˝¸¸¸¸¸¸˚˚˚˙˙˙ */ + $"FAFA F9F9 F9F8 F8F8 F8F8 F7F7 F7F6 F6F6" /* ˙˙˘˘˘¯¯¯¯¯˜˜˜ˆˆˆ */ + $"F6F6 F5F5 F5F4 F4F4 F4F4 F0ED EDEC ECEC" /* ˆˆıııÙÙÙÙÙÌÌÏÏÏ */ + $"EBEB EAEA EAE9 E9E9 E8E8 E8E7 E7E6 E6EA" /* ÎÎÍÍÍÈÈÈËËËÁÁÊÊÍ */ + $"C50B 0000 2BE6 EDEC ECED EDED EEEE EEEF" /* ≈...+ÊÌÏÏÌÌÌÓÓÓÔ */ + $"EFF0 F0F0 F1F1 F1F2 F2F2 F6F7 F7F7 F7FA" /* ÔÒÒÒÚÚÚˆ˜˜˜˜˙ */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* ˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇ */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* ˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇ */ + $"FFFE FDFD FDFC FCFC FCFC FBFB FBFA FAFA" /* ˇ˛˝˝˝¸¸¸¸¸˚˚˚˙˙˙ */ + $"F9F9 F9F9 F9F8 F8F8 F7F7 F7F7 F7F6 F6F6" /* ˘˘˘˘˘¯¯¯˜˜˜˜˜ˆˆˆ */ + $"F5F5 F5F5 F5F4 F4F4 F3F3 F0ED EDED ECEC" /* ıııııÙÙÙÛÛÌÌÌÏÏ */ + $"EBEB EBEA EAEA E9E9 E8E8 E8E7 E7E7 E6E7" /* ÎÎÎÍÍÍÈÈËËËÁÁÁÊÁ */ + $"E129 0000 55F3 EBEC ECEC EDED EEEE EEEF" /* ·)..UÛÎÏÏÏÌÌÓÓÓÔ */ + $"EFF0 F0F0 F1F1 F1F2 F2F2 F4F7 F7F7 F7FA" /* ÔÒÒÒÚÚÚÙ˜˜˜˜˙ */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* ˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇ */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* ˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇ */ + $"FEFE FDFD FDFC FCFC FBFB FBFB FBFA FAFA" /* ˛˛˝˝˝¸¸¸˚˚˚˚˚˙˙˙ */ + $"F9F9 F9F9 F9F8 F8F8 F7F7 F7F7 F7F7 F6F6" /* ˘˘˘˘˘¯¯¯˜˜˜˜˜˜ˆˆ */ + $"F5F5 F5F4 F4F4 F4F4 F4F1 EEED EDED ECEC" /* ıııÙÙÙÙÙÙÒÓÌÌÌÏÏ */ + $"ECEB EBEA EAEA E9E9 E9E8 E8E7 E7E7 E6E6" /* ÏÎÎÍÍÍÈÈÈËËÁÁÁÊÊ */ + $"EE52 0000 81F5 EBEC ECEC EDED EDEE EEEF" /* ÓR..ÅıÎÏÏÏÌÌÌÓÓÔ */ + $"EFEF F0F0 F0F1 F1F1 F2F2 F3F6 F6F7 F7FA" /* ÔÔÒÒÒÚÚÛˆˆ˜˜˙ */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* ˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇ */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFE" /* ˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇ˛ */ + $"FEFE FEFD FDFC FCFC FBFB FBFB FBFB FAFA" /* ˛˛˛˝˝¸¸¸˚˚˚˚˚˚˙˙ */ + $"F9F9 F9F9 F9F9 F8F8 F7F7 F7F6 F6F6 F6F6" /* ˘˘˘˘˘˘¯¯˜˜˜ˆˆˆˆˆ */ + $"F6F5 F5F4 F4F4 F4F4 F4EF EEED EDED ECEC" /* ˆııÙÙÙÙÙÙÔÓÌÌÌÏÏ */ + $"ECEB EBEB EAEA E9E9 E9E8 E8E8 E7E7 E7E6" /* ÏÎÎÎÍÍÈÈÈËËËÁÁÁÊ */ + $"F07E 0000 A7F3 EBEB ECEC EDED EDEE EEEE" /* ~..ßÛÎÎÏÏÌÌÌÓÓÓ */ + $"EFEF EFF0 F0F1 F1F1 F2F2 F2F4 F6F7 F7FA" /* ÔÔÔÒÒÒÚÚÚÙˆ˜˜˙ */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* ˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇ */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FEFE" /* ˇˇˇˇˇˇˇˇˇˇˇˇˇˇ˛˛ */ + $"FEFE FEFD FDFD FCFC FCFB FBFB FBFB FAFA" /* ˛˛˛˝˝˝¸¸¸˚˚˚˚˚˙˙ */ + $"FAF9 F9F8 F8F8 F8F8 F8F7 F7F7 F6F6 F5F5" /* ˙˘˘¯¯¯¯¯¯˜˜˜ˆˆıı */ + $"F5F5 F5F5 F4F4 F3F3 F2EE EEEE EDED EDEC" /* ııııÙÙÛÛÚÓÓÓÌÌÌÏ */ + $"ECEB EBEB EAEA EAE9 E9E8 E8E8 E7E7 E7E6" /* ÏÎÎÎÍÍÍÈÈËËËÁÁÁÊ */ + $"EDA4 0007 C6EF EBEB ECEC ECED EDED EEEE" /* ̧..∆ÔÎÎÏÏÏÌÌÌÓÓ */ + $"EFEF EFF0 F0F0 F1F1 F2F2 F2F3 F5F6 F7FA" /* ÔÔÔÒÒÚÚÚÛıˆ˜˙ */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* ˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇ */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFE FEFE" /* ˇˇˇˇˇˇˇˇˇˇˇˇˇ˛˛˛ */ + $"FEFE FEFD FDFD FCFC FCFB FBFB FBFB FAFA" /* ˛˛˛˝˝˝¸¸¸˚˚˚˚˚˙˙ */ + $"FAF9 F9F9 F8F8 F8F8 F8F7 F7F7 F6F6 F6F5" /* ˙˘˘˘¯¯¯¯¯˜˜˜ˆˆˆı */ + $"F5F5 F5F5 F4F4 F4F3 F0EE EEEE EDED EDEC" /* ııııÙÙÙÛÓÓÓÌÌÌÏ */ + $"ECEC EBEB EAEA EAE9 E9E9 E8E8 E7E7 E7E6" /* ÏÏÎÎÍÍÍÈÈÈËËÁÁÁÊ */ + $"EBC3 0716 D9ED EBEB EBEC ECED EDED EEEE" /* Î√..ŸÌÎÎÎÏÏÌÌÌÓÓ */ + $"EEEF EFEF F0F0 F1F1 F1F2 F2F2 F4F6 F6F9" /* ÓÔÔÔÒÒÒÚÚÚÙˆˆ˘ */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* ˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇ */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FEFD FDFD" /* ˇˇˇˇˇˇˇˇˇˇˇˇ˛˝˝˝ */ + $"FDFD FDFD FDFD FCFC FCFB FBFB FAFA FAFA" /* ˝˝˝˝˝˝¸¸¸˚˚˚˙˙˙˙ */ + $"FAF9 F9F9 F8F8 F8F7 F7F7 F7F7 F6F6 F6F5" /* ˙˘˘˘¯¯¯˜˜˜˜˜ˆˆˆı */ + $"F5F5 F4F4 F4F4 F4F2 EFEF EEEE EEED EDEC" /* ııÙÙÙÙÙÚÔÔÓÓÓÌÌÏ */ + $"ECEC EBEB EBEA EAE9 E9E9 E8E8 E8E7 E7E7" /* ÏÏÎÎÎÍÍÈÈÈËËËÁÁÁ */ + $"E8D6 162B E7EB EBEB EBEC ECEC EDED EDEE" /* Ë÷.+ÁÎÎÎÎÏÏÏÌÌÌÓ */ + $"EEEF EFEF F0F0 F0F1 F1F2 F2F2 F3F5 F6F8" /* ÓÔÔÔÒÒÚÚÚÛıˆ¯ */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* ˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇ */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FDFD FDFD" /* ˇˇˇˇˇˇˇˇˇˇˇˇ˝˝˝˝ */ + $"FDFD FDFD FDFD FCFC FCFB FBFB FAFA FAFA" /* ˝˝˝˝˝˝¸¸¸˚˚˚˙˙˙˙ */ + $"FAF9 F9F9 F8F8 F8F7 F7F7 F7F7 F6F6 F6F5" /* ˙˘˘˘¯¯¯˜˜˜˜˜ˆˆˆı */ + $"F5F5 F4F4 F4F3 F3F0 EFEF EEEE EEED EDED" /* ııÙÙÙÛÛÔÔÓÓÓÌÌÌ */ + $"ECEC EBEB EBEA EAEA E9E9 E9E8 E8E7 E7E7" /* ÏÏÎÎÎÍÍÍÈÈÈËËÁÁÁ */ + $"E7E3 2A42 EEEA EAEB EBEB ECEC EDED EDEE" /* Á„*BÓÍÍÎÎÎÏÏÌÌÌÓ */ + $"EEEE EFEF F0F0 F0F1 F1F1 F2F2 F2F3 F5F7" /* ÓÓÔÔÒÒÒÚÚÚÛı˜ */ + $"FEFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* ˛ˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇ */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FDFD FDFD" /* ˇˇˇˇˇˇˇˇˇˇˇˇ˝˝˝˝ */ + $"FDFD FDFD FDFD FCFC FCFB FBFB FAFA FAF9" /* ˝˝˝˝˝˝¸¸¸˚˚˚˙˙˙˘ */ + $"F9F9 F9F9 F8F8 F8F7 F7F7 F6F6 F6F6 F6F5" /* ˘˘˘˘¯¯¯˜˜˜ˆˆˆˆˆı */ + $"F5F5 F4F4 F4F3 F1F0 EFEF EEEE EEED EDED" /* ııÙÙÙÛÒÔÔÓÓÓÌÌÌ */ + $"ECEC ECEB EBEA EAEA E9E9 E9E8 E8E8 E7E7" /* ÏÏÏÎÎÍÍÍÈÈÈËËËÁÁ */ + $"E7EA 4153 F2EA EAEB EBEB ECEC ECED EDEE" /* ÁÍASÚÍÍÎÎÎÏÏÏÌÌÓ */ + $"EEEE EFEF EFF0 F0F0 F1F1 F1F2 F2F3 F4F5" /* ÓÓÔÔÔÒÒÒÚÚÛÙı */ + $"FDFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* ˝ˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇ */ + $"FFFF FFFF FFFF FFFF FFFF FFFE FDFD FDFD" /* ˇˇˇˇˇˇˇˇˇˇˇ˛˝˝˝˝ */ + $"FDFD FDFD FDFD FCFC FCFB FBFB FAFA FAF9" /* ˝˝˝˝˝˝¸¸¸˚˚˚˙˙˙˘ */ + $"F9F9 F9F9 F9F8 F8F7 F7F7 F6F6 F6F5 F5F5" /* ˘˘˘˘˘¯¯˜˜˜ˆˆˆııı */ + $"F5F5 F5F4 F4F2 F0F0 EFEF EFEE EEEE EDED" /* ıııÙÙÚÔÔÔÓÓÓÌÌ */ + $"ECEC ECEB EBEB EAEA E9E9 E9E8 E8E8 E7E7" /* ÏÏÏÎÎÎÍÍÈÈÈËËËÁÁ */ + $"E7EE 5274 F1EA EAEA EBEB EBEC ECED EDED" /* ÁÓRtÒÍÍÍÎÎÎÏÏÌÌÌ */ + $"EEEE EEEF EFF0 F0F0 F1F1 F1F2 F2F2 F3F4" /* ÓÓÓÔÔÒÒÒÚÚÚÛÙ */ + $"FCFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* ¸ˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇ */ + $"FFFF FFFF FFFF FFFF FFFF FFFE FDFD FDFD" /* ˇˇˇˇˇˇˇˇˇˇˇ˛˝˝˝˝ */ + $"FDFD FDFD FDFC FCFC FCFB FBFB FAFA FAF9" /* ˝˝˝˝˝¸¸¸¸˚˚˚˙˙˙˘ */ + $"F9F9 F8F8 F8F8 F8F8 F7F7 F7F6 F6F5 F5F5" /* ˘˘¯¯¯¯¯¯˜˜˜ˆˆııı */ + $"F4F4 F4F4 F3F1 F0F0 EFEF EFEE EEEE EDED" /* ÙÙÙÙÛÒÔÔÔÓÓÓÌÌ */ + $"EDEC ECEB EBEB EAEA EAE9 E9E9 E8E8 E7E7" /* ÌÏÏÎÎÎÍÍÍÈÈÈËËÁÁ */ + $"E7EE 73A7 EEE9 EAEA EBEB EBEC ECEC EDED" /* ÁÓsßÓÈÍÍÎÎÎÏÏÏÌÌ */ + $"EDEE EEEF EFEF F0F0 F0F1 F1F1 F2F2 F3F3" /* ÌÓÓÔÔÔÒÒÒÚÚÛÛ */ + $"FBFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* ˚ˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇ */ + $"FFFF FFFF FFFF FFFF FFFF FFFE FDFD FDFD" /* ˇˇˇˇˇˇˇˇˇˇˇ˛˝˝˝˝ */ + $"FDFD FDFD FDFC FCFC FCFB FBFB FAFA FAF9" /* ˝˝˝˝˝¸¸¸¸˚˚˚˙˙˙˘ */ + $"F9F9 F8F8 F8F8 F8F8 F7F7 F7F6 F6F6 F5F5" /* ˘˘¯¯¯¯¯¯˜˜˜ˆˆˆıı */ + $"F4F4 F4F3 F1F1 F0F0 F0EF EFEE EEEE EDED" /* ÙÙÙÛÒÒÔÔÓÓÓÌÌ */ + $"EDEC ECEC EBEB EAEA EAE9 E9E9 E8E8 E8E7" /* ÌÏÏÏÎÎÍÍÍÈÈÈËËËÁ */ + $"E7EB A5C2 ECE9 EAEA EAEB EBEC ECEC EDED" /* ÁΕ¬ÏÈÍÍÍÎÎÏÏÏÌÌ */ + $"EDEE EEEE EFEF F0F0 F0F1 F1F1 F2F2 F2F3" /* ÌÓÓÓÔÔÒÒÒÚÚÚÛ */ + $"FBFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* ˚ˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇ */ + $"FFFF FFFF FFFF FFFF FFFF FFFD FCFC FCFC" /* ˇˇˇˇˇˇˇˇˇˇˇ˝¸¸¸¸ */ + $"FCFC FCFC FCFC FCFC FCFB FBFB FAFA FAF9" /* ¸¸¸¸¸¸¸¸¸˚˚˚˙˙˙˘ */ + $"F9F9 F8F8 F8F7 F7F7 F7F7 F7F6 F6F6 F5F5" /* ˘˘¯¯¯˜˜˜˜˜˜ˆˆˆıı */ + $"F4F4 F4F2 F1F1 F0F0 F0EF EFEF EEEE EDED" /* ÙÙÙÚÒÒÔÔÔÓÓÌÌ */ + $"EDEC ECEC EBEB EBEA EAE9 E9E9 E8E8 E8E7" /* ÌÏÏÏÎÎÎÍÍÈÈÈËËËÁ */ + $"E7E9 BFD1 EBE9 E9EA EAEB EBEB ECEC ECED" /* ÁÈø—ÎÈÈÍÍÎÎÎÏÏÏÌ */ + $"EDED EEEE EFEF EFF0 F0F0 F1F1 F1F2 F2F2" /* ÌÌÓÓÔÔÔÒÒÒÚÚÚ */ + $"FBFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* ˚ˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇ */ + $"FFFF FFFF FFFF FFFF FFFF FFFC FCFC FCFC" /* ˇˇˇˇˇˇˇˇˇˇˇ¸¸¸¸¸ */ + $"FCFC FCFC FCFC FCFC FBFB FBFB FAFA FAF9" /* ¸¸¸¸¸¸¸¸˚˚˚˚˙˙˙˘ */ + $"F9F9 F8F8 F8F7 F7F7 F6F6 F6F6 F6F6 F5F5" /* ˘˘¯¯¯˜˜˜ˆˆˆˆˆˆıı */ + $"F5F4 F3F2 F1F1 F0F0 F0EF EFEF EEEE EEED" /* ıÙÛÚÒÒÔÔÔÓÓÓÌ */ + $"EDEC ECEC EBEB EBEA EAEA E9E9 E8E8 E8E7" /* ÌÏÏÏÎÎÎÍÍÍÈÈËËËÁ */ + $"E7E9 CEE1 E9E9 E9EA EAEA EBEB EBEC ECED" /* ÁÈŒ·ÈÈÈÍÍÍÎÎÎÏÏÌ */ + $"EDED EEEE EEEF EFEF F0F0 F0F1 F1F2 F2F2" /* ÌÌÓÓÓÔÔÔÒÒÚÚÚ */ + $"FAFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* ˙ˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇ */ + $"FFFF FFFF FFFF FFFF FFFF FFFC FCFC FCFC" /* ˇˇˇˇˇˇˇˇˇˇˇ¸¸¸¸¸ */ + $"FCFC FCFC FCFC FCFC FBFB FBFB FAFA FAF9" /* ¸¸¸¸¸¸¸¸˚˚˚˚˙˙˙˘ */ + $"F9F9 F8F8 F8F7 F7F7 F6F6 F6F5 F5F5 F5F5" /* ˘˘¯¯¯˜˜˜ˆˆˆııııı */ + $"F5F3 F2F2 F1F1 F1F0 F0EF EFEF EEEE EEED" /* ıÛÚÚÒÒÒÔÔÔÓÓÓÌ */ + $"EDED ECEC EBEB EBEA EAEA E9E9 E9E8 E8E7" /* ÌÌÏÏÎÎÎÍÍÍÈÈÈËËÁ */ + $"E7E7 DFE1 E9E9 E9E9 EAEA EBEB EBEC ECEC" /* ÁÁfl·ÈÈÈÈÍÍÎÎÎÏÏÏ */ + $"EDED EDEE EEEF EFEF F0F0 F0F1 F1F1 F2F1" /* ÌÌÌÓÓÔÔÔÒÒÒÚÒ */ + $"F9FF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* ˘ˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇ */ + $"FFFF FFFF FFFF FFFF FFFF FFFC FBFB FBFB" /* ˇˇˇˇˇˇˇˇˇˇˇ¸˚˚˚˚ */ + $"FBFB FBFB FBFB FBFB FBFB FBFA FAFA FAF9" /* ˚˚˚˚˚˚˚˚˚˚˚˙˙˙˙˘ */ + $"F9F9 F8F8 F8F7 F7F7 F6F6 F6F5 F5F5 F4F4" /* ˘˘¯¯¯˜˜˜ˆˆˆıııÙÙ */ + $"F3F2 F2F2 F1F1 F1F0 F0F0 EFEF EEEE EEED" /* ÛÚÚÚÒÒÒÔÔÓÓÓÌ */ + $"EDED ECEC ECEB EBEA EAEA E9E9 E9E8 E8E8" /* ÌÌÏÏÏÎÎÍÍÍÈÈÈËËË */ + $"E7E7 E0D0 EAE9 E9E9 EAEA EAEB EBEB ECEC" /* ÁÁ‡–ÍÈÈÈÍÍÍÎÎÎÏÏ */ + $"EDED EDEE EEEE EFEF EFF0 F0F0 F1F1 F2F1" /* ÌÌÌÓÓÓÔÔÔÒÒÚÒ */ + $"F9FF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* ˘ˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇ */ + $"FFFF FFFF FFFF FFFF FFFF FFFB FAFB FBFB" /* ˇˇˇˇˇˇˇˇˇˇˇ˚˙˚˚˚ */ + $"FBFB FBFB FBFB FAFA FAFA FAFA FAFA FAF9" /* ˚˚˚˚˚˚˙˙˙˙˙˙˙˙˙˘ */ + $"F9F9 F8F8 F8F7 F7F7 F6F6 F6F5 F5F5 F4F3" /* ˘˘¯¯¯˜˜˜ˆˆˆıııÙÛ */ + $"F3F2 F2F2 F1F1 F1F0 F0F0 EFEF EFEE EEED" /* ÛÚÚÚÒÒÒÔÔÔÓÓÌ */ + $"EDED ECEC ECEB EBEB EAEA E9E9 E9E8 E8E8" /* ÌÌÏÏÏÎÎÎÍÍÈÈÈËËË */ + $"E7E8 D2C1 EBE8 E9E9 E9EA EAEB EBEB ECEC" /* ÁË“¡ÎËÈÈÈÍÍÎÎÎÏÏ */ + $"ECED EDED EEEE EFEF EFF0 F0F0 F1F1 F1F1" /* ÏÌÌÌÓÓÔÔÔÒÒÒÒ */ + $"F7FF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* ˜ˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇ */ + $"FFFF FFFF FFFF FFFF FFFF FFFB FAFA FAFB" /* ˇˇˇˇˇˇˇˇˇˇˇ˚˙˙˙˚ */ + $"FBFB FBFB FAFA FAFA FAFA FAF9 F9F9 F9F9" /* ˚˚˚˚˙˙˙˙˙˙˙˘˘˘˘˘ */ + $"F9F9 F8F8 F8F7 F7F7 F6F6 F6F6 F5F5 F4F3" /* ˘˘¯¯¯˜˜˜ˆˆˆˆııÙÛ */ + $"F3F2 F2F2 F1F1 F1F0 F0F0 EFEF EFEE EEEE" /* ÛÚÚÚÒÒÒÔÔÔÓÓÓ */ + $"EDED ECEC ECEB EBEB EAEA EAE9 E9E9 E8E8" /* ÌÌÏÏÏÎÎÎÍÍÍÈÈÈËË */ + $"E7EA C2A6 EDE8 E9E9 E9EA EAEA EBEB EBEC" /* Áͬ¶ÌËÈÈÈÍÍÍÎÎÎÏ */ + $"ECED EDED EEEE EEEF EFEF F0F0 F0F1 F1F1" /* ÏÌÌÌÓÓÓÔÔÔÒÒÒ */ + $"F4FF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* Ùˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇ */ + $"FFFF FFFF FFFF FFFF FFFF FFFC FAFA FAFA" /* ˇˇˇˇˇˇˇˇˇˇˇ¸˙˙˙˙ */ + $"FAFA FAFA FAFA FAFA FAFA F9F9 F9F9 F8F8" /* ˙˙˙˙˙˙˙˙˙˙˘˘˘˘¯¯ */ + $"F8F8 F8F8 F8F7 F7F7 F6F6 F6F6 F4F4 F4F3" /* ¯¯¯¯¯˜˜˜ˆˆˆˆÙÙÙÛ */ + $"F3F3 F2F2 F1F1 F1F0 F0F0 EFEF EFEE EEEE" /* ÛÛÚÚÒÒÒÔÔÔÓÓÓ */ + $"EDED ECEC ECEB EBEB EAEA EAE9 E9E9 E8E8" /* ÌÌÏÏÏÎÎÎÍÍÍÈÈÈËË */ + $"E7EC A073 F0E8 E8E9 E9E9 EAEA EAEB EBEC" /* ÁφsËËÈÈÈÍÍÍÎÎÏ */ + $"ECEC EDED EDEE EEEE EFEF EFF0 F0F1 F1F1" /* ÏÏÌÌÌÓÓÓÔÔÔÒÒÒ */ + $"F2FC FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* Ú¸ˇˇˇˇˇˇˇˇˇˇˇˇˇˇ */ + $"FFFF FFFF FFFF FFFF FFFF FFFC FAFA FAFA" /* ˇˇˇˇˇˇˇˇˇˇˇ¸˙˙˙˙ */ + $"FAFA FAFA FAFA FAFA FAF9 F9F9 F9F9 F8F8" /* ˙˙˙˙˙˙˙˙˙˘˘˘˘˘¯¯ */ + $"F8F8 F7F7 F7F6 F6F6 F6F6 F6F5 F4F4 F4F3" /* ¯¯˜˜˜ˆˆˆˆˆˆıÙÙÙÛ */ + $"F3F3 F2F2 F1F1 F1F0 F0F0 EFEF EFEE EEEE" /* ÛÛÚÚÒÒÒÔÔÔÓÓÓ */ + $"EDED EDEC ECEC EBEB EAEA EAE9 E9E9 E8E8" /* ÌÌÌÏÏÏÎÎÍÍÍÈÈÈËË */ + $"E8EF 7752 EFE8 E8E9 E9E9 EAEA EAEB EBEB" /* ËÔwRÔËËÈÈÈÍÍÍÎÎÎ */ + $"ECEC ECED EDED EEEE EFEF EFF0 F0F0 F1F1" /* ÏÏÏÌÌÌÓÓÔÔÔÒÒ */ + $"F1F6 FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* Òˆˇˇˇˇˇˇˇˇˇˇˇˇˇˇ */ + $"FFFF FFFF FFFF FFFF FFFF FFFD F9F9 FAFA" /* ˇˇˇˇˇˇˇˇˇˇˇ˝˘˘˙˙ */ + $"FAFA FAFA FAFA FAFA F9F9 F9F9 F9F9 F8F8" /* ˙˙˙˙˙˙˙˙˘˘˘˘˘˘¯¯ */ + $"F8F8 F7F7 F7F6 F6F6 F5F5 F5F5 F4F4 F4F3" /* ¯¯˜˜˜ˆˆˆııııÙÙÙÛ */ + $"F3F3 F2F2 F2F1 F1F1 F0F0 EFEF EFEE EEEE" /* ÛÛÚÚÚÒÒÒÔÔÔÓÓÓ */ + $"EDED EDEC ECEC EBEB EBEA EAE9 E9E9 E8E8" /* ÌÌÌÏÏÏÎÎÎÍÍÈÈÈËË */ + $"E8F0 5641 EBE8 E8E8 E9E9 E9EA EAEA EBEB" /* ËVAÎËËËÈÈÈÍÍÍÎÎ */ + $"EBEC ECED EDED EEEE EEEF EFEF F0F0 F0F1" /* ÎÏÏÌÌÌÓÓÓÔÔÔÒ */ + $"F1F1 F9FF FFFF FFFF FFFF FFFF FFFF FFFF" /* ÒÒ˘ˇˇˇˇˇˇˇˇˇˇˇˇˇ */ + $"FFFF FFFF FFFF FFFF FFFF FFFD F9F9 F9F9" /* ˇˇˇˇˇˇˇˇˇˇˇ˝˘˘˘˘ */ + $"F9FA FAFA FAFA F9F9 F9F9 F9F9 F9F8 F8F8" /* ˘˙˙˙˙˙˘˘˘˘˘˘˘¯¯¯ */ + $"F8F7 F7F7 F7F6 F6F6 F5F5 F5F5 F4F4 F4F3" /* ¯˜˜˜˜ˆˆˆııııÙÙÙÛ */ + $"F3F3 F2F2 F2F1 F1F1 F0F0 F0EF EFEF EEEE" /* ÛÛÚÚÚÒÒÒÔÔÔÓÓ */ + $"EDED EDEC ECEC EBEB EBEA EAEA E9E9 E9E8" /* ÌÌÌÏÏÏÎÎÎÍÍÍÈÈÈË */ + $"E8EC 402A E4E8 E8E8 E9E9 E9EA EAEA EBEB" /* ËÏ@*‰ËËËÈÈÈÍÍÍÎÎ */ + $"EBEC ECEC EDED EDEE EEEE EFEF F0F0 F0F1" /* ÎÏÏÏÌÌÌÓÓÓÔÔÒ */ + $"F1F1 F1F8 FFFF FFFF FFFF FFFF FFFF FFFF" /* ÒÒÒ¯ˇˇˇˇˇˇˇˇˇˇˇˇ */ + $"FFFF FFFF FFFF FFFF FFFF FFFE F9F9 F9F9" /* ˇˇˇˇˇˇˇˇˇˇˇ˛˘˘˘˘ */ + $"F9F9 F9F9 F9F9 F9F9 F9F9 F9F9 F8F8 F8F8" /* ˘˘˘˘˘˘˘˘˘˘˘˘¯¯¯¯ */ + $"F8F7 F7F7 F7F6 F6F6 F5F5 F5F5 F4F4 F4F3" /* ¯˜˜˜˜ˆˆˆııııÙÙÙÛ */ + $"F3F3 F2F2 F2F1 F1F1 F0F0 F0EF EFEF EEEE" /* ÛÛÚÚÚÒÒÒÔÔÔÓÓ */ + $"EEED EDEC ECEC EBEB EBEA EAEA E9E9 E9E8" /* ÓÌÌÏÏÏÎÎÎÍÍÍÈÈÈË */ + $"E9E5 2C16 D7E9 E8E8 E8E9 E9E9 EAEA EAEB" /* ÈÂ,.◊ÈËËËÈÈÈÍÍÍÎ */ + $"EBEB ECEC ECED EDEE EEEE EFEF EFF0 F0F0" /* ÎÎÏÏÏÌÌÓÓÓÔÔÔ */ + $"F1F1 F1F1 F6FE FFFF FFFF FFFF FFFF FFFF" /* ÒÒÒÒˆ˛ˇˇˇˇˇˇˇˇˇˇ */ + $"FFFF FFFF FFFF FFFF FFFF FFFF F9F9 F9F9" /* ˇˇˇˇˇˇˇˇˇˇˇˇ˘˘˘˘ */ + $"F9F9 F9F9 F9F9 F9F9 F9F9 F9F8 F8F8 F8F8" /* ˘˘˘˘˘˘˘˘˘˘˘¯¯¯¯¯ */ + $"F8F7 F7F7 F7F6 F6F6 F5F5 F5F5 F4F4 F4F3" /* ¯˜˜˜˜ˆˆˆııııÙÙÙÛ */ + $"F3F3 F2F2 F2F1 F1F1 F0F0 F0EF EFEF EEEE" /* ÛÛÚÚÚÒÒÒÔÔÔÓÓ */ + $"EEED EDED ECEC EBEB EBEA EAEA E9E9 E9E8" /* ÓÌÌÌÏÏÎÎÎÍÍÍÈÈÈË */ + $"EAD9 1907 C4EC E7E8 E8E8 E9E9 E9EA EAEB" /* ÍŸ..ƒÏÁËËËÈÈÈÍÍÎ */ + $"EBEB ECEC ECED EDED EEEE EEEF EFEF F0F0" /* ÎÎÏÏÏÌÌÌÓÓÓÔÔÔ */ + $"F0F1 F1F1 F2F5 FEFF FFFF FFFF FFFF FFFF" /* ÒÒÒÚı˛ˇˇˇˇˇˇˇˇˇ */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FAF8 F8F9" /* ˇˇˇˇˇˇˇˇˇˇˇˇ˙¯¯˘ */ + $"F9F9 F9F9 F9F9 F9F9 F9F9 F8F8 F8F8 F8F8" /* ˘˘˘˘˘˘˘˘˘˘¯¯¯¯¯¯ */ + $"F7F7 F7F7 F6F6 F6F6 F5F5 F5F4 F4F4 F4F3" /* ˜˜˜˜ˆˆˆˆıııÙÙÙÙÛ */ + $"F3F3 F2F2 F2F1 F1F1 F0F0 F0EF EFEF EEEE" /* ÛÛÚÚÚÒÒÒÔÔÔÓÓ */ + $"EEED EDED ECEC ECEB EBEA EAEA E9E9 E9E8" /* ÓÌÌÌÏÏÏÎÎÍÍÍÈÈÈË */ + $"EDC4 0700 A5EE E7E8 E8E8 E9E9 E9EA EAEA" /* ̃..•ÓÁËËËÈÈÈÍÍÍ */ + $"EBEB EBEC ECEC EDED EDEE EEEE EFEF EFF0" /* ÎÎÎÏÏÏÌÌÌÓÓÓÔÔÔ */ + $"F0F0 F1F1 F2F2 F5FE FFFF FFFF FFFF FFFF" /* ÒÒÚÚı˛ˇˇˇˇˇˇˇˇ */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FBF8 F8F8" /* ˇˇˇˇˇˇˇˇˇˇˇˇ˚¯¯¯ */ + $"F8F8 F9F9 F9F9 F9F9 F8F8 F8F8 F8F8 F8F7" /* ¯¯˘˘˘˘˘˘¯¯¯¯¯¯¯˜ */ + $"F7F7 F7F7 F6F6 F6F6 F5F5 F5F4 F4F4 F4F3" /* ˜˜˜˜ˆˆˆˆıııÙÙÙÙÛ */ + $"F3F3 F2F2 F2F1 F1F1 F0F0 F0EF EFEF EEEE" /* ÛÛÚÚÚÒÒÒÔÔÔÓÓ */ + $"EEED EDED ECEC ECEB EBEA EAEA E9E9 E9E8" /* ÓÌÌÌÏÏÏÎÎÍÍÍÈÈÈË */ + $"EFA9 0000 7EF0 E7E7 E8E8 E8E9 E9E9 EAEA" /* Ô©..~ÁÁËËËÈÈÈÍÍ */ + $"EAEB EBEB ECEC EDED EDEE EEEE EFEF EFF0" /* ÍÎÎÎÏÏÌÌÌÓÓÓÔÔÔ */ + $"F0F0 F1F1 F1F2 F2F5 FEFF FFFF FFFF FFFF" /* ÒÒÒÚÚı˛ˇˇˇˇˇˇˇ */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FDF8 F8F8" /* ˇˇˇˇˇˇˇˇˇˇˇˇ˝¯¯¯ */ + $"F8F8 F8F8 F8F8 F8F8 F8F8 F8F8 F8F8 F7F7" /* ¯¯¯¯¯¯¯¯¯¯¯¯¯¯˜˜ */ + $"F7F7 F7F6 F6F6 F6F6 F5F5 F5F4 F4F4 F4F3" /* ˜˜˜ˆˆˆˆˆıııÙÙÙÙÛ */ + $"F3F3 F2F2 F2F1 F1F1 F0F0 F0EF EFEF EEEE" /* ÛÛÚÚÚÒÒÒÔÔÔÓÓ */ + $"EEED EDED ECEC ECEB EBEB EAEA EAE9 E9E8" /* ÓÌÌÌÏÏÏÎÎÎÍÍÍÈÈË */ + $"F282 0000 53EE E7E7 E7E8 E8E8 E9E9 EAEA" /* ÚÇ..SÓÁÁÁËËËÈÈÍÍ */ + $"EAEB EBEB ECEC ECED EDED EEEE EEEF EFEF" /* ÍÎÎÎÏÏÏÌÌÌÓÓÓÔÔÔ */ + $"EFF0 F0F1 F1F1 F2F2 F6FF FFFF FFFF FFFF" /* ÔÒÒÒÚÚˆˇˇˇˇˇˇˇ */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FEF8 F8F8" /* ˇˇˇˇˇˇˇˇˇˇˇˇ˛¯¯¯ */ + $"F8F8 F8F8 F8F8 F8F8 F8F8 F8F8 F8F7 F7F7" /* ¯¯¯¯¯¯¯¯¯¯¯¯¯˜˜˜ */ + $"F7F7 F7F6 F6F6 F6F5 F5F5 F5F4 F4F4 F3F3" /* ˜˜˜ˆˆˆˆııııÙÙÙÛÛ */ + $"F3F3 F2F2 F2F1 F1F1 F0F0 F0EF EFEF EEEE" /* ÛÛÚÚÚÒÒÒÔÔÔÓÓ */ + $"EEED EDED ECEC ECEB EBEB EAEA EAE9 E9E9" /* ÓÌÌÌÏÏÏÎÎÎÍÍÍÈÈÈ */ + $"EF53 0000 2AE1 E7E7 E7E8 E8E8 E9E9 E9EA" /* ÔS..*·ÁÁÁËËËÈÈÈÍ */ + $"EAEA EBEB EBEC ECEC EDED EDEE EEEE EFEF" /* ÍÍÎÎÎÏÏÏÌÌÌÓÓÓÔÔ */ + $"EFEF F0F0 F1F1 F1F2 F1F6 FFFF FFFF FFFF" /* ÔÔÒÒÒÚÒˆˇˇˇˇˇˇ */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFF9 F7F7" /* ˇˇˇˇˇˇˇˇˇˇˇˇˇ˘˜˜ */ + $"F8F8 F8F8 F8F8 F8F8 F8F8 F8F8 F7F7 F7F7" /* ¯¯¯¯¯¯¯¯¯¯¯¯˜˜˜˜ */ + $"F7F7 F6F6 F6F6 F6F5 F5F5 F5F4 F4F4 F3F3" /* ˜˜ˆˆˆˆˆııııÙÙÙÛÛ */ + $"F3F3 F2F2 F2F1 F1F1 F0F0 F0EF EFEF EEEE" /* ÛÛÚÚÚÒÒÒÔÔÔÓÓ */ + $"EEED EDED ECEC ECEB EBEB EAEA EAE9 E9EA" /* ÓÌÌÌÏÏÏÎÎÎÍÍÍÈÈÍ */ + $"E42B 0000 0BC6 EAE7 E7E7 E8E8 E8E9 E9E9" /* ‰+...∆ÍÁÁÁËËËÈÈÈ */ + $"EAEA EAEB EBEB ECEC ECED EDED EEEE EEEF" /* ÍÍÍÎÎÎÏÏÏÌÌÌÓÓÓÔ */ + $"EFEF F0F0 F0F1 F1F1 F2F2 F7FF FFFF FFFF" /* ÔÔÒÒÒÚÚ˜ˇˇˇˇˇ */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFB F7F7" /* ˇˇˇˇˇˇˇˇˇˇˇˇˇ˚˜˜ */ + $"F7F7 F7F7 F8F8 F8F8 F8F7 F7F7 F7F7 F7F7" /* ˜˜˜˜¯¯¯¯¯˜˜˜˜˜˜˜ */ + $"F7F6 F6F6 F6F6 F5F5 F5F5 F5F4 F4F4 F3F3" /* ˜ˆˆˆˆˆıııııÙÙÙÛÛ */ + $"F3F3 F2F2 F2F1 F1F1 F0F0 F0EF EFEF EEEE" /* ÛÛÚÚÚÒÒÒÔÔÔÓÓ */ + $"EEED EDED ECEC ECEB EBEB EAEA EAE9 E9EE" /* ÓÌÌÌÏÏÏÎÎÎÍÍÍÈÈÓ */ + $"C90B 0000 009B EEE6 E7E7 E7E8 E8E8 E9E9" /* …....õÓÊÁÁÁËËËÈÈ */ + $"E9EA EAEB EBEB ECEC ECED EDED EEEE EEEF" /* ÈÍÍÎÎÎÏÏÏÌÌÌÓÓÓÔ */ + $"EFEF EFF0 F0F0 F1F1 F1F2 F2F9 FFFF FFFF" /* ÔÔÔÒÒÒÚÚ˘ˇˇˇˇ */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFD F7F7" /* ˇˇˇˇˇˇˇˇˇˇˇˇˇ˝˜˜ */ + $"F7F7 F7F7 F7F7 F7F7 F7F7 F7F7 F7F7 F7F7" /* ˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜ */ + $"F6F6 F6F6 F6F6 F5F5 F5F5 F4F4 F4F4 F3F3" /* ˆˆˆˆˆˆııııÙÙÙÙÛÛ */ + $"F3F2 F2F2 F2F1 F1F1 F0F0 F0EF EFEF EEEE" /* ÛÚÚÚÚÒÒÒÔÔÔÓÓ */ + $"EEED EDED ECEC ECEB EBEB EAEA EAE9 E9F1" /* ÓÌÌÌÏÏÏÎÎÎÍÍÍÈÈÒ */ + $"9D00 0000 0060 EFE6 E7E7 E7E8 E8E8 E9E9" /* ù....`ÔÊÁÁÁËËËÈÈ */ + $"E9EA EAEA EBEB EBEC ECEC EDED EDEE EEEE" /* ÈÍÍÍÎÎÎÏÏÏÌÌÌÓÓÓ */ + $"EFEF EFEF F0F0 F1F1 F1F1 F2F2 FAFF FFFF" /* ÔÔÔÔÒÒÒÒÚÚ˙ˇˇˇ */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF F8F7" /* ˇˇˇˇˇˇˇˇˇˇˇˇˇˇ¯˜ */ + $"F7F7 F7F7 F7F7 F7F7 F7F7 F7F7 F7F7 F7F6" /* ˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜ˆ */ + $"F6F6 F6F6 F6F5 F5F5 F5F5 F4F4 F4F4 F3F3" /* ˆˆˆˆˆıııııÙÙÙÙÛÛ */ + $"F3F2 F2F2 F2F1 F1F1 F0F0 F0EF EFEF EEEE" /* ÛÚÚÚÚÒÒÒÔÔÔÓÓ */ + $"EEED EDED ECEC ECEB EBEB EAEA EAE9 E9F1" /* ÓÌÌÌÏÏÏÎÎÎÍÍÍÈÈÒ */ + $"6200 0000 0027 DFE7 E6E7 E7E7 E8E8 E8E9" /* b....'flÁÊÁÁÁËËËÈ */ + $"E9E9 EAEA EAEB EBEB ECEC ECED EDED EEEE" /* ÈÈÍÍÍÎÎÎÏÏÏÌÌÌÓÓ */ + $"EEEF EFEF EFF0 F0F1 F1F1 F2F2 F2FB FFFF" /* ÓÔÔÔÔÒÒÒÚÚÚ˚ˇˇ */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FAF6" /* ˇˇˇˇˇˇˇˇˇˇˇˇˇˇ˙ˆ */ + $"F6F6 F7F7 F7F7 F7F7 F7F7 F7F7 F7F6 F6F6" /* ˆˆ˜˜˜˜˜˜˜˜˜˜˜ˆˆˆ */ + $"F6F6 F6F6 F6F5 F5F5 F5F4 F4F4 F4F3 F3F3" /* ˆˆˆˆˆııııÙÙÙÙÛÛÛ */ + $"F3F2 F2F2 F2F1 F1F1 F0F0 F0EF EFEF EEEE" /* ÛÚÚÚÚÒÒÒÔÔÔÓÓ */ + $"EEED EDED EDEC ECEC EBEB EBEA EAEA EAE5" /* ÓÌÌÌÌÏÏÏÎÎÎÍÍÍÍ */ + $"2B00 0000 0005 B9EB E6E6 E7E7 E7E8 E8E9" /* +.....πÎÊÊÁÁÁËËÈ */ + $"E9E9 EAEA EAEB EBEB ECEC ECED EDED EDEE" /* ÈÈÍÍÍÎÎÎÏÏÏÌÌÌÌÓ */ + $"EEEE EFEF EFEF F0F0 F1F1 F1F2 F2F3 FDFF" /* ÓÓÔÔÔÔÒÒÒÚÚÛ˝ˇ */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FDF6" /* ˇˇˇˇˇˇˇˇˇˇˇˇˇˇ˝ˆ */ + $"F6F6 F6F6 F6F6 F6F7 F7F6 F6F6 F6F6 F6F6" /* ˆˆˆˆˆˆˆ˜˜ˆˆˆˆˆˆˆ */ + $"F6F6 F6F6 F5F5 F5F5 F5F4 F4F4 F4F3 F3F3" /* ˆˆˆˆıııııÙÙÙÙÛÛÛ */ + $"F3F2 F2F2 F1F1 F1F1 F0F0 F0EF EFEF EEEE" /* ÛÚÚÚÒÒÒÒÔÔÔÓÓ */ + $"EEED EDED EDEC ECEC EBEB EBEA EAEA EFBE" /* ÓÌÌÌÌÏÏÏÎÎÎÍÍÍÔæ */ + $"0700 0000 0000 79EF E6E6 E7E7 E7E8 E8E8" /* ......yÔÊÊÁÁÁËËË */ + $"E9E9 E9EA EAEA EBEB EBEC ECEC EDED EDEE" /* ÈÈÈÍÍÍÎÎÎÏÏÏÌÌÌÓ */ + $"EEEE EEEF EFEF F0F0 F0F1 F1F1 F2F2 F4FE" /* ÓÓÓÔÔÔÒÒÒÚÚÙ˛ */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFF7" /* ˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇ˜ */ + $"F6F6 F6F6 F6F6 F6F6 F6F6 F6F6 F6F6 F6F6" /* ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ */ + $"F6F6 F5F5 F5F5 F5F5 F4F4 F4F4 F4F3 F3F3" /* ˆˆııııııÙÙÙÙÙÛÛÛ */ + $"F2F2 F2F2 F1F1 F1F1 F0F0 F0EF EFEF EEEE" /* ÚÚÚÚÒÒÒÒÔÔÔÓÓ */ + $"EEED EDED EDEC ECEC EBEB EBEA EAEA F27B" /* ÓÌÌÌÌÏÏÏÎÎÎÍÍÍÚ{ */ + $"0000 0000 0000 32E3 E6E6 E6E7 E7E7 E8E8" /* ......2„ÊÊÊÁÁÁËË */ + $"E8E9 E9E9 EAEA EAEB EBEB ECEC ECED EDED" /* ËÈÈÈÍÍÍÎÎÎÏÏÏÌÌÌ */ + $"EEEE EEEF EFEF EFF0 F0F0 F1F1 F1F2 F2F5" /* ÓÓÓÔÔÔÔÒÒÒÚÚı */ + $"FEFF FFFF FFFF FFFF FFFF FFFF FFFF FFFA" /* ˛ˇˇˇˇˇˇˇˇˇˇˇˇˇˇ˙ */ + $"F5F6 F6F6 F6F6 F6F6 F6F6 F6F6 F6F6 F6F6" /* ıˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ */ + $"F6F5 F5F5 F5F5 F5F5 F4F4 F4F4 F3F3 F3F3" /* ˆıııııııÙÙÙÙÛÛÛÛ */ + $"F2F2 F2F2 F1F1 F1F1 F0F0 F0EF EFEF EEEE" /* ÚÚÚÚÒÒÒÒÔÔÔÓÓ */ + $"EEED EDED EDEC ECEC EBEB EBEA EAEA E836" /* ÓÌÌÌÌÏÏÏÎÎÎÍÍÍË6 */ + $"0000 0000 0000 07BA EAE6 E6E6 E7E7 E7E8" /* .......∫ÍÊÊÊÁÁÁË */ + $"E8E8 E9E9 E9EA EAEA EBEB EBEC ECEC EDED" /* ËËÈÈÈÍÍÍÎÎÎÏÏÏÌÌ */ + $"EDEE EEEE EFEF EFEF F0F0 F0F1 F1F1 F2F2" /* ÌÓÓÓÔÔÔÔÒÒÒÚÚ */ + $"F7FF FFFF FFFF FFFF FFFF FFFF FFFF FFFD" /* ˜ˇˇˇˇˇˇˇˇˇˇˇˇˇˇ˝ */ + $"F5F5 F5F6 F6F6 F6F6 F6F6 F6F6 F6F6 F6F5" /* ıııˆˆˆˆˆˆˆˆˆˆˆˆı */ + $"F5F5 F5F5 F5F5 F5F4 F4F4 F4F4 F3F3 F3F3" /* ıııııııÙÙÙÙÙÛÛÛÛ */ + $"F2F2 F2F2 F1F1 F1F0 F0F0 F0EF EFEF EEEE" /* ÚÚÚÚÒÒÒÔÔÔÓÓ */ + $"EEED EDED EDEC ECEC EBEB EBEA EAF0 B907" /* ÓÌÌÌÌÏÏÏÎÎÎÍÍπ. */ + $"0000 0000 0000 006D EEE6 E6E6 E7E7 E7E8" /* .......mÓÊÊÊÁÁÁË */ + $"E8E8 E9E9 E9EA EAEA EBEB EBEB ECEC ECED" /* ËËÈÈÈÍÍÍÎÎÎÎÏÏÏÌ */ + $"EDED EEEE EEEF EFEF EFF0 F0F0 F1F1 F1F1" /* ÌÌÓÓÓÔÔÔÔÒÒÒÒ */ + $"F2F9 FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* Ú˘ˇˇˇˇˇˇˇˇˇˇˇˇˇˇ */ + $"F7F5 F5F5 F5F5 F5F5 F5F5 F5F5 F5F5 F5F5" /* ˜ııııııııııııııı */ + $"F5F5 F5F5 F5F5 F4F4 F4F4 F4F3 F3F3 F3F2" /* ııııııÙÙÙÙÙÛÛÛÛÚ */ + $"F2F2 F2F2 F1F1 F1F0 F0F0 F0EF EFEF EEEE" /* ÚÚÚÚÒÒÒÔÔÔÓÓ */ + $"EEED EDED EDEC ECEC EBEB EBEA EAF2 6700" /* ÓÌÌÌÌÏÏÏÎÎÎÍÍÚg. */ + $"0000 0000 0000 0020 D9E7 E6E6 E6E7 E7E7" /* ....... ŸÁÊÊÊÁÁÁ */ + $"E8E8 E8E9 E9E9 EAEA EAEB EBEB ECEC ECED" /* ËËËÈÈÈÍÍÍÎÎÎÏÏÏÌ */ + $"EDED EDEE EEEE EFEF EFEF F0F0 F0F1 F1F1" /* ÌÌÌÓÓÓÔÔÔÔÒÒÒ */ + $"F1F2 FBFF FFFF FFFF FFFF FFFF FFFF FFFF" /* ÒÚ˚ˇˇˇˇˇˇˇˇˇˇˇˇˇ */ + $"F9F5 F5F5 F5F5 F5F5 F5F5 F5F5 F5F5 F5F5" /* ˘ııııııııııııııı */ + $"F5F5 F5F5 F5F4 F4F4 F4F4 F4F3 F3F3 F3F2" /* ıııııÙÙÙÙÙÙÛÛÛÛÚ */ + $"F2F2 F2F1 F1F1 F1F0 F0F0 EFEF EFEF EEEE" /* ÚÚÚÒÒÒÒÔÔÔÔÓÓ */ + $"EEED EDED EDEC ECEC EBEB EBEA EDDB 1E00" /* ÓÌÌÌÌÏÏÏÎÎÎÍÌ€.. */ + $"0000 0000 0000 0000 9AED E5E6 E6E6 E7E7" /* ........öÌÂÊÊÊÁÁ */ + $"E7E8 E8E8 E9E9 E9EA EAEA EBEB EBEC ECEC" /* ÁËËËÈÈÈÍÍÍÎÎÎÏÏÏ */ + $"EDED EDEE EEEE EEEF EFEF EFF0 F0F0 F1F1" /* ÌÌÌÓÓÓÓÔÔÔÔÒÒ */ + $"F1F1 F3FD FFFF FFFF FFFF FFFF FFFF FFFF" /* ÒÒÛ˝ˇˇˇˇˇˇˇˇˇˇˇˇ */ + $"FDF4 F5F5 F5F5 F5F5 F5F5 F5F5 F5F5 F5F5" /* ˝Ùıııııııııııııı */ + $"F5F5 F5F4 F4F4 F4F4 F4F4 F3F3 F3F3 F3F2" /* ıııÙÙÙÙÙÙÙÛÛÛÛÛÚ */ + $"F2F2 F2F1 F1F1 F1F0 F0F0 EFEF EFEF EEEE" /* ÚÚÚÒÒÒÒÔÔÔÔÓÓ */ + $"EEED EDED EDEC ECEC EBEB EBEA F299 0000" /* ÓÌÌÌÌÏÏÏÎÎÎÍÚô.. */ + $"0000 0000 0000 0000 3DE6 E5E6 E6E6 E7E7" /* ........=ÊÂÊÊÊÁÁ */ + $"E7E8 E8E8 E8E9 E9E9 EAEA EAEB EBEB ECEC" /* ÁËËËËÈÈÈÍÍÍÎÎÎÏÏ */ + $"ECED EDED EEEE EEEE EFEF EFEF F0F0 F0F1" /* ÏÌÌÌÓÓÓÓÔÔÔÔÒ */ + $"F1F1 F1F5 FFFF FFFF FFFF FFFF FFFF FFFF" /* ÒÒÒıˇˇˇˇˇˇˇˇˇˇˇˇ */ + $"FFF6 F4F4 F4F5 F5F5 F5F5 F5F5 F5F5 F5F5" /* ˇˆÙÙÙııııııııııı */ + $"F5F4 F4F4 F4F4 F4F4 F4F3 F3F3 F3F3 F2F2" /* ıÙÙÙÙÙÙÙÙÛÛÛÛÛÚÚ */ + $"F2F2 F2F1 F1F1 F1F0 F0F0 EFEF EFEF EEEE" /* ÚÚÚÒÒÒÒÔÔÔÔÓÓ */ + $"EEED EDED ECEC ECEC EBEB EBEB EC40 0000" /* ÓÌÌÌÏÏÏÏÎÎÎÎÏ@.. */ + $"0000 0000 0000 0000 04AF EBE5 E6E6 E6E7" /* .........ØÎÂÊÊÊÁ */ + $"E7E7 E8E8 E8E9 E9E9 EAEA EAEB EBEB EBEC" /* ÁÁËËËÈÈÈÍÍÍÎÎÎÎÏ */ + $"ECEC EDED EDEE EEEE EFEF EFEF EFF0 F0F0" /* ÏÏÌÌÌÓÓÓÔÔÔÔÔ */ + $"F1F1 F1F1 F7FF FFFF FFFF FFFF FFFF FFFF" /* ÒÒÒÒ˜ˇˇˇˇˇˇˇˇˇˇˇ */ + $"FFF9 F4F4 F4F4 F4F4 F4F4 F4F4 F4F4 F4F4" /* ˇ˘ÙÙÙÙÙÙÙÙÙÙÙÙÙÙ */ + $"F4F4 F4F4 F4F4 F4F4 F3F3 F3F3 F3F3 F2F2" /* ÙÙÙÙÙÙÙÙÛÛÛÛÛÛÚÚ */ + $"F2F2 F1F1 F1F1 F0F0 F0F0 EFEF EFEF EEEE" /* ÚÚÒÒÒÒÔÔÔÔÓÓ */ + $"EEED EDED ECEC ECEC EBEB EBF1 AF05 0000" /* ÓÌÌÌÏÏÏÏÎÎÎÒØ... */ + $"0000 0000 0000 0000 004F EAE5 E5E6 E6E6" /* .........OÍÂÂÊÊÊ */ + $"E7E7 E7E8 E8E8 E9E9 E9EA EAEA EBEB EBEC" /* ÁÁÁËËËÈÈÈÍÍÍÎÎÎÏ */ + $"ECEC ECED EDED EEEE EEEE EFEF EFEF F0F0" /* ÏÏÏÌÌÌÓÓÓÓÔÔÔÔ */ + $"F0F1 F1F1 F1FA FFFF FFFF FFFF FFFF FFFF" /* ÒÒÒÒ˙ˇˇˇˇˇˇˇˇˇˇ */ + $"FFFD F4F4 F4F4 F4F4 F4F4 F4F4 F4F4 F4F4" /* ˇ˝ÙÙÙÙÙÙÙÙÙÙÙÙÙÙ */ + $"F4F4 F4F4 F4F4 F3F3 F3F3 F3F3 F3F2 F2F2" /* ÙÙÙÙÙÙÛÛÛÛÛÛÛÚÚÚ */ + $"F2F2 F1F1 F1F1 F0F0 F0EF EFEF EFEE EEEE" /* ÚÚÒÒÒÒÔÔÔÔÓÓÓ */ + $"EEED EDED ECEC ECEC EBEB ECEC 4900 0000" /* ÓÌÌÌÏÏÏÏÎÎÏÏI... */ + $"0000 0000 0000 0000 0008 B5EB E5E5 E6E6" /* ..........µÎÂÂÊÊ */ + $"E6E7 E7E7 E8E8 E8E9 E9E9 EAEA EAEB EBEB" /* ÊÁÁÁËËËÈÈÈÍÍÍÎÎÎ */ + $"ECEC ECEC EDED EDEE EEEE EEEF EFEF EFF0" /* ÏÏÏÏÌÌÌÓÓÓÓÔÔÔÔ */ + $"F0F0 F1F1 F1F2 FDFF FFFF FFFF FFFF FFFF" /* ÒÒÒÚ˝ˇˇˇˇˇˇˇˇˇ */ + $"FFFF F5F3 F4F4 F4F4 F4F4 F4F4 F4F4 F4F4" /* ˇˇıÛÙÙÙÙÙÙÙÙÙÙÙÙ */ + $"F4F4 F4F4 F4F3 F3F3 F3F3 F3F3 F2F2 F2F2" /* ÙÙÙÙÙÛÛÛÛÛÛÛÚÚÚÚ */ + $"F2F1 F1F1 F1F1 F0F0 F0EF EFEF EFEE EEEE" /* ÚÒÒÒÒÒÔÔÔÔÓÓÓ */ + $"EEED EDED ECEC ECEC EBEB F1B5 0600 0000" /* ÓÌÌÌÏÏÏÏÎÎÒµ.... */ + $"0000 0000 0000 0000 0000 4CE9 E5E5 E6E6" /* ..........LÈÂÂÊÊ */ + $"E6E7 E7E7 E8E8 E8E8 E9E9 E9EA EAEA EBEB" /* ÊÁÁÁËËËËÈÈÈÍÍÍÎÎ */ + $"EBEC ECEC EDED EDED EEEE EEEE EFEF EFEF" /* ÎÏÏÏÌÌÌÌÓÓÓÓÔÔÔÔ */ + $"EFF0 F0F0 F1F1 F4FE FFFF FFFF FFFF FFFF" /* ÔÒÒÙ˛ˇˇˇˇˇˇˇˇ */ + $"FFFF F9F3 F3F3 F4F4 F4F4 F4F4 F4F4 F4F4" /* ˇˇ˘ÛÛÛÙÙÙÙÙÙÙÙÙÙ */ + $"F4F4 F3F3 F3F3 F3F3 F3F3 F3F2 F2F2 F2F2" /* ÙÙÛÛÛÛÛÛÛÛÛÚÚÚÚÚ */ + $"F1F1 F1F1 F1F0 F0F0 F0EF EFEF EFEE EEEE" /* ÒÒÒÒÒÔÔÔÔÓÓÓ */ + $"EEED EDED ECEC ECEB EBEC EE4D 0000 0000" /* ÓÌÌÌÏÏÏÎÎÏÓM.... */ + $"0000 0000 0000 0000 0000 06AB ECE5 E5E6" /* ...........´ÏÂÂÊ */ + $"E6E6 E7E7 E7E8 E8E8 E9E9 E9E9 EAEA EAEB" /* ÊÊÁÁÁËËËÈÈÈÈÍÍÍÎ */ + $"EBEB ECEC ECEC EDED EDEE EEEE EEEF EFEF" /* ÎÎÏÏÏÏÌÌÌÓÓÓÓÔÔÔ */ + $"EFEF F0F0 F0F1 F0F7 FFFF FFFF FFFF FFFF" /* ÔÔÒ˜ˇˇˇˇˇˇˇˇ */ + $"FFFF FCF3 F3F3 F3F3 F3F3 F3F3 F3F3 F3F3" /* ˇˇ¸ÛÛÛÛÛÛÛÛÛÛÛÛÛ */ + $"F3F3 F3F3 F3F3 F3F3 F3F3 F2F2 F2F2 F2F2" /* ÛÛÛÛÛÛÛÛÛÛÚÚÚÚÚÚ */ + $"F1F1 F1F1 F0F0 F0F0 EFEF EFEF EFEE EEEE" /* ÒÒÒÒÔÔÔÔÔÓÓÓ */ + $"EDED EDED ECEC ECEB EBF1 B007 0000 0000" /* ÌÌÌÌÏÏÏÎÎÒ∞..... */ + $"0000 0000 0000 0000 0000 003A E2E6 E5E5" /* ...........:‚Ê */ + $"E6E6 E6E7 E7E7 E8E8 E8E9 E9E9 EAEA EAEA" /* ÊÊÊÁÁÁËËËÈÈÈÍÍÍÍ */ + $"EBEB EBEC ECEC ECED EDED EEEE EEEE EFEF" /* ÎÎÎÏÏÏÏÌÌÌÓÓÓÓÔÔ */ + $"EFEF EFF0 F0F0 F1F1 FBFF FFFF FFFF FFFF" /* ÔÔÔÒÒ˚ˇˇˇˇˇˇˇ */ + $"FFFF FFF5 F3F3 F3F3 F3F3 F3F3 F3F3 F3F3" /* ˇˇˇıÛÛÛÛÛÛÛÛÛÛÛÛ */ + $"F3F3 F3F3 F3F3 F3F3 F2F2 F2F2 F2F2 F2F1" /* ÛÛÛÛÛÛÛÛÚÚÚÚÚÚÚÒ */ + $"F1F1 F1F1 F0F0 F0F0 EFEF EFEF EEEE EEEE" /* ÒÒÒÒÔÔÔÔÓÓÓÓ */ + $"EDED EDED ECEC ECEB EDE6 3900 0000 0000" /* ÌÌÌÌÏÏÏÎÌÊ9..... */ + $"0000 0000 0000 0000 0000 0000 8EED E5E5" /* ............éÌ */ + $"E5E6 E6E6 E7E7 E7E8 E8E8 E9E9 E9EA EAEA" /* ÂÊÊÊÁÁÁËËËÈÈÈÍÍÍ */ + $"EAEB EBEB ECEC ECEC EDED EDEE EEEE EEEF" /* ÍÎÎÎÏÏÏÏÌÌÌÓÓÓÓÔ */ + $"EFEF EFEF F0F0 F0F0 F3FE FFFF FFFF FFFF" /* ÔÔÔÔÛ˛ˇˇˇˇˇˇ */ + $"FFFF FFF8 F2F3 F3F3 F3F3 F3F3 F3F3 F3F3" /* ˇˇˇ¯ÚÛÛÛÛÛÛÛÛÛÛÛ */ + $"F3F3 F3F3 F3F3 F2F2 F2F2 F2F2 F2F2 F1F1" /* ÛÛÛÛÛÛÚÚÚÚÚÚÚÚÒÒ */ + $"F1F1 F1F0 F0F0 F0EF EFEF EFEF EEEE EEEE" /* ÒÒÒÔÔÔÔÔÓÓÓÓ */ + $"EDED EDED ECEC ECEB F38B 0000 0000 0000" /* ÌÌÌÌÏÏÏÎÛã...... */ + $"0000 0000 0000 0000 0000 0000 1ECF E8E5" /* .............œË */ + $"E5E6 E6E6 E7E7 E7E7 E8E8 E8E9 E9E9 EAEA" /* ÂÊÊÊÁÁÁÁËËËÈÈÈÍÍ */ + $"EAEA EBEB EBEC ECEC EDED EDED EEEE EEEE" /* ÍÍÎÎÎÏÏÏÌÌÌÌÓÓÓÓ */ + $"EFEF EFEF EFEF F0F0 F0F6 FFFF FFFF FFFF" /* ÔÔÔÔÔÔˆˇˇˇˇˇˇ */ + $"FFFF FFFB F2F2 F2F2 F3F3 F3F3 F3F3 F3F3" /* ˇˇˇ˚ÚÚÚÚÛÛÛÛÛÛÛÛ */ + $"F3F3 F3F3 F2F2 F2F2 F2F2 F2F2 F2F1 F1F1" /* ÛÛÛÛÚÚÚÚÚÚÚÚÚÒÒÒ */ + $"F1F1 F1F0 F0F0 F0EF EFEF EFEF EEEE EEEE" /* ÒÒÒÔÔÔÔÔÓÓÓÓ */ + $"EDED EDEC ECEC ECF0 D31C 0000 0000 0000" /* ÌÌÌÏÏÏÏ”....... */ + $"0000 0000 0000 0000 0000 0000 005B E9E5" /* .............[È */ + $"E5E5 E6E6 E6E7 E7E7 E8E8 E8E8 E9E9 E9EA" /* ÂÂÊÊÊÁÁÁËËËËÈÈÈÍ */ + $"EAEA EBEB EBEB ECEC ECEC EDED EDEE EEEE" /* ÍÍÎÎÎÎÏÏÏÏÌÌÌÓÓÓ */ + $"EEEF EFEF EFEF EFF0 F0F0 F9FF FFFF FFFF" /* ÓÔÔÔÔÔÔ˘ˇˇˇˇˇ */ + $"FFFF FFFE F3F2 F2F2 F2F2 F2F2 F2F2 F2F2" /* ˇˇˇ˛ÛÚÚÚÚÚÚÚÚÚÚÚ */ + $"F2F2 F2F2 F2F2 F2F2 F2F2 F2F2 F1F1 F1F1" /* ÚÚÚÚÚÚÚÚÚÚÚÚÒÒÒÒ */ + $"F1F1 F0F0 F0F0 EFEF EFEF EFEE EEEE EEED" /* ÒÒÔÔÔÔÔÓÓÓÓÌ */ + $"EDED EDEC ECEC EDEF 6200 0000 0000 0000" /* ÌÌÌÏÏÏÌÔb....... */ + $"0000 0000 0000 0000 0000 0000 0005 A2EC" /* ..............¢Ï */ + $"E5E5 E5E6 E6E6 E7E7 E7E8 E8E8 E8E9 E9E9" /* ÂÂÂÊÊÊÁÁÁËËËËÈÈÈ */ + $"EAEA EAEB EBEB EBEC ECEC ECED EDED EEEE" /* ÍÍÍÎÎÎÎÏÏÏÏÌÌÌÓÓ */ + $"EEEE EEEF EFEF EFEF F0F0 F1FC FFFF FFFF" /* ÓÓÓÔÔÔÔÔÒ¸ˇˇˇˇ */ + $"FFFF FFFF F5F2 F2F2 F2F2 F2F2 F2F2 F2F2" /* ˇˇˇˇıÚÚÚÚÚÚÚÚÚÚÚ */ + $"F2F2 F2F2 F2F2 F2F2 F2F2 F1F1 F1F1 F1F1" /* ÚÚÚÚÚÚÚÚÚÚÒÒÒÒÒÒ */ + $"F1F0 F0F0 F0F0 EFEF EFEF EFEE EEEE EEED" /* ÒÔÔÔÔÔÓÓÓÓÌ */ + $"EDED EDEC ECED F2A1 0500 0000 0000 0000" /* ÌÌÌÏÏÌÚ°........ */ + $"0000 0000 0000 0000 0000 0000 0000 22CE" /* .............."Œ */ + $"E8E5 E5E5 E6E6 E6E7 E7E7 E8E8 E8E9 E9E9" /* ËÂÂÂÊÊÊÁÁÁËËËÈÈÈ */ + $"E9EA EAEA EBEB EBEB ECEC ECED EDED EDEE" /* ÈÍÍÍÎÎÎÎÏÏÏÌÌÌÌÓ */ + $"EEEE EEEE EFEF EFEF EFEF F0F3 FFFF FFFF" /* ÓÓÓÓÔÔÔÔÔÔÛˇˇˇˇ */ + $"FFFF FFFF F8F1 F2F2 F2F2 F2F2 F2F2 F2F2" /* ˇˇˇˇ¯ÒÚÚÚÚÚÚÚÚÚÚ */ + $"F2F2 F2F2 F2F2 F2F2 F1F1 F1F1 F1F1 F1F1" /* ÚÚÚÚÚÚÚÚÒÒÒÒÒÒÒÒ */ + $"F0F0 F0F0 F0EF EFEF EFEF EEEE EEEE EEED" /* ÔÔÔÔÔÓÓÓÓÓÌ */ + $"EDED ECEC ECEF D01E 0000 0000 0000 0000" /* ÌÌÏÏÏÔ–......... */ + $"0000 0000 0000 0000 0000 0000 0000 004C" /* ...............L */ + $"DFE7 E5E5 E5E6 E6E6 E7E7 E7E7 E8E8 E9E9" /* flÁÂÂÂÊÊÊÁÁÁÁËËÈÈ */ + $"E9E9 EAEA EAEB EBEB EBEC ECEC ECED EDED" /* ÈÈÍÍÍÎÎÎÎÏÏÏÏÌÌÌ */ + $"EDEE EEEE EEEF EFEF EFEF EFEF F8FF FFFF" /* ÌÓÓÓÓÔÔÔÔÔÔÔ¯ˇˇˇ */ + $"FFFF FFFF FCF1 F1F1 F1F1 F2F2 F2F2 F2F2" /* ˇˇˇˇ¸ÒÒÒÒÒÚÚÚÚÚÚ */ + $"F2F2 F2F2 F2F1 F1F1 F1F1 F1F1 F1F1 F1F0" /* ÚÚÚÚÚÒÒÒÒÒÒÒÒÒÒ */ + $"F0F0 F0F0 EFEF EFEF EFEF EEEE EEEE EDED" /* ÔÔÔÔÔÔÓÓÓÓÌÌ */ + $"EDED ECEC EEE6 4900 0000 0000 0000 0000" /* ÌÌÏÏÓÊI......... */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"7AE8 E6E5 E5E6 E6E6 E6E7 E7E7 E7E8 E8E9" /* zËÊÂÂÊÊÊÊÁÁÁÁËËÈ */ + $"E9E9 E9EA EAEA EBEB EBEB ECEC ECEC EDED" /* ÈÈÈÍÍÍÎÎÎÎÏÏÏÏÌÌ */ + $"EDED EEEE EEEE EFEF EFEF EFEF F0FC FFFF" /* ÌÌÓÓÓÓÔÔÔÔÔÔ¸ˇˇ */ + $"FFFF FFFF FEF2 F1F1 F1F1 F1F1 F1F1 F1F1" /* ˇˇˇˇ˛ÚÒÒÒÒÒÒÒÒÒÒ */ + $"F1F1 F1F1 F1F1 F1F1 F1F1 F1F1 F1F1 F0F0" /* ÒÒÒÒÒÒÒÒÒÒÒÒÒÒ */ + $"F0F0 F0EF EFEF EFEF EFEE EEEE EEEE EDED" /* ÔÔÔÔÔÔÓÓÓÓÓÌÌ */ + $"EDED ECEC F4A4 0000 0000 0000 0000 0000" /* ÌÌÏÏÙ§.......... */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0AA0 E9E6 E5E5 E6E6 E6E7 E7E7 E7E7 E8E8" /* ¬†ÈÊÂÂÊÊÊÁÁÁÁÁËË */ + $"E9E9 E9E9 EAEA EAEB EBEB EBEC ECEC ECED" /* ÈÈÈÈÍÍÍÎÎÎÎÏÏÏÏÌ */ + $"EDED EDEE EEEE EEEE EFEF EFEF EFF3 FFFF" /* ÌÌÌÓÓÓÓÓÔÔÔÔÔÛˇˇ */ + $"FFFF FFFF FFF4 F0F1 F1F1 F1F1 F1F1 F1F1" /* ˇˇˇˇˇÙÒÒÒÒÒÒÒÒÒ */ + $"F1F1 F1F1 F1F1 F1F1 F1F1 F1F1 F0F0 F0F0" /* ÒÒÒÒÒÒÒÒÒÒÒÒ */ + $"F0F0 EFEF EFEF EFEF EFEE EEEE EEED EDED" /* ÔÔÔÔÔÔÔÓÓÓÓÌÌÌ */ + $"EDED ECEC F1C0 0D00 0000 0000 0000 0000" /* ÌÌÏÏÒ¿.......... */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"001D BBE9 E6E5 E5E6 E6E6 E7E7 E7E7 E7E8" /* ..ªÈÊÂÂÊÊÊÁÁÁÁÁË */ + $"E8E9 E9E9 E9EA EAEA EBEB EBEB ECEC ECEC" /* ËÈÈÈÈÍÍÍÎÎÎÎÏÏÏÏ */ + $"EDED EDED EDEE EEEE EEEF EFEF EFEF F8FF" /* ÌÌÌÌÌÓÓÓÓÔÔÔÔÔ¯ˇ */ + $"FFFF FFFF FFF6 EFF1 F1F1 F1F1 F1F1 F1F1" /* ˇˇˇˇˇˆÔÒÒÒÒÒÒÒÒÒ */ + $"F1F1 F1F1 F1F1 F1F1 F1F1 F0F0 F0F0 F0F0" /* ÒÒÒÒÒÒÒÒÒÒ */ + $"F0EF EFEF EFEF EFEF EEEE EEEE EEED EDED" /* ÔÔÔÔÔÔÔÓÓÓÓÓÌÌÌ */ + $"EDEC ECEC ECEF 4A00 0000 0000 0000 0000" /* ÌÏÏÏÏÔJ......... */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 31CA E8E6 E5E5 E6E6 E6E7 E7E7 E7E8" /* ..1 ËÊÂÂÊÊÊÁÁÁÁË */ + $"E8E8 E9E9 E9E9 EAEA EAEA EBEB EBEC ECEC" /* ËËÈÈÈÈÍÍÍÍÎÎÎÏÏÏ */ + $"ECED EDED EDED EEEE EEEE EEEF EFEF F0FC" /* ÏÌÌÌÌÌÓÓÓÓÓÔÔÔ¸ */ + $"FFFF FFFF FFF8 F0F0 F0F0 F0F1 F1F1 F1F1" /* ˇˇˇˇˇ¯ÒÒÒÒÒ */ + $"F1F1 F1F1 F1F1 F1F0 F0F0 F0F0 F0F0 F0F0" /* ÒÒÒÒÒÒÒ */ + $"EFEF EFEF EFEF EFEE EEEE EEEE EDED EDED" /* ÔÔÔÔÔÔÔÓÓÓÓÓÌÌÌÌ */ + $"EDEC ECEC ECF3 A003 0000 0000 0000 0000" /* ÌÏÏÏÏÛ†......... */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0044 D4E8 E5E5 E5E6 E6E6 E7E7 E7E7" /* ...D‘ËÂÂÂÊÊÊÁÁÁÁ */ + $"E8E8 E8E9 E9E9 E9EA EAEA EBEB EBEB ECEC" /* ËËËÈÈÈÈÍÍÍÎÎÎÎÏÏ */ + $"ECEC EDED EDED EDEE EEEE EEEE EFEF EEF4" /* ÏÏÌÌÌÌÌÓÓÓÓÓÔÔÓÙ */ + $"FFFF FFFF FFFA F0F0 F0F0 F0F0 F0F0 F0F0" /* ˇˇˇˇˇ˙ */ + $"F0F0 F0F0 F0F0 F0F0 F0F0 F0F0 F0F0 EFEF" /* ÔÔ */ + $"EFEF EFEF EFEF EEEE EEEE EEEE EDED EDED" /* ÔÔÔÔÔÔÓÓÓÓÓÓÌÌÌÌ */ + $"ECEC ECEC ECED E026 0000 0000 0000 0000" /* ÏÏÏÏÏ̇&........ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 51D7 E8E5 E5E5 E6E6 E6E7 E7E7" /* ....Q◊ËÂÂÂÊÊÊÁÁÁ */ + $"E7E7 E8E8 E9E9 E9E9 EAEA EAEB EBEB EBEB" /* ÁÁËËÈÈÈÈÍÍÍÎÎÎÎÎ */ + $"ECEC ECEC EDED EDED EDEE EEEE EEEE EFEF" /* ÏÏÏÏÌÌÌÌÌÓÓÓÓÓÔÔ */ + $"FAFF FFFF FFFB F0EF EFF0 F0F0 F0F0 F0F0" /* ˙ˇˇˇˇ˚ÔÔ */ + $"F0F0 F0F0 F0F0 F0F0 F0F0 F0F0 EFEF EFEF" /* ÔÔÔÔ */ + $"EFEF EFEF EFEE EEEE EEEE EEED EDED EDED" /* ÔÔÔÔÔÓÓÓÓÓÓÌÌÌÌÌ */ + $"ECEC ECEC EBEB F577 0000 0000 0000 0000" /* ÏÏÏÏÎÎıw........ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0059 D9E8 E6E5 E5E6 E6E6 E7E7" /* .....YŸËÊÂÂÊÊÊÁÁ */ + $"E7E7 E7E8 E8E9 E9E9 E9EA EAEA EAEB EBEB" /* ÁÁÁËËÈÈÈÈÍÍÍÍÎÎÎ */ + $"EBEC ECEC ECED EDED EDED EEEE EEEE EEEE" /* ÎÏÏÏÏÌÌÌÌÌÓÓÓÓÓÓ */ + $"F1FF FFFF FFFD F0EF EFEF EFEF EFEF F0F0" /* Òˇˇˇˇ˝ÔÔÔÔÔÔÔ */ + $"F0F0 F0F0 F0F0 F0F0 EFEF EFEF EFEF EFEF" /* ÔÔÔÔÔÔÔÔ */ + $"EFEF EFEF EEEE EEEE EEEE EDED EDED EDEC" /* ÔÔÔÔÓÓÓÓÓÓÌÌÌÌÌÏ */ + $"ECEC ECEC EBEB EFC6 0F00 0000 0000 0000" /* ÏÏÏÏÎÎÔ∆........ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 59D6 E7E6 E5E5 E6E6 E6E7" /* ......Y÷ÁÊÂÂÊÊÊÁ */ + $"E7E7 E7E8 E8E8 E9E9 E9E9 EAEA EAEA EBEB" /* ÁÁÁËËËÈÈÈÈÍÍÍÍÎÎ */ + $"EBEB ECEC ECEC ECED EDED EDED EEEE EEEE" /* ÎÎÏÏÏÏÏÌÌÌÌÌÓÓÓÓ */ + $"EDF6 FFFF FFFE F0EF EFEF EFEF EFEF EFEF" /* ̈ˇˇˇ˛ÔÔÔÔÔÔÔÔÔ */ + $"EFEF EFEF EFEF EFEF EFEF EFEF EFEF EFEF" /* ÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔ */ + $"EFEF EFEE EEEE EEEE EEED EDED EDED ECEC" /* ÔÔÔÓÓÓÓÓÓÌÌÌÌÌÏÏ */ + $"ECEC ECEB EBEB EBEF 4C00 0000 0000 0000" /* ÏÏÏÎÎÎÎÔL....... */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0051 D2E7 E6E5 E6E6 E6E6" /* .......Q“ÁÊÂÊÊÊÊ */ + $"E7E7 E7E7 E8E8 E8E9 E9E9 E9EA EAEA EAEB" /* ÁÁÁÁËËËÈÈÈÈÍÍÍÍÎ */ + $"EBEB EBEC ECEC ECEC EDED EDED EDEE EEEE" /* ÎÎÎÏÏÏÏÏÌÌÌÌÌÓÓÓ */ + $"EEEF FCFF FFFE F1EF EFEF EFEF EFEF EFEF" /* ÓÔ¸ˇˇ˛ÒÔÔÔÔÔÔÔÔÔ */ + $"EFEF EFEF EFEF EFEF EFEF EFEF EFEF EFEF" /* ÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔ */ + $"EFEF EEEE EEEE EEEE EEED EDED EDED ECEC" /* ÔÔÓÓÓÓÓÓÓÌÌÌÌÌÏÏ */ + $"ECEC ECEB EBEB EBF2 A203 0000 0000 0000" /* ÏÏÏÎÎÎÎÚ¢....... */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 45C7 E7E6 E5E6 E6E6" /* ........E«ÁÊÂÊÊÊ */ + $"E6E7 E7E7 E7E7 E8E8 E9E9 E9E9 EAEA EAEA" /* ÊÁÁÁÁÁËËÈÈÈÈÍÍÍÍ */ + $"EBEB EBEB EBEC ECEC ECEC EDED EDED EDED" /* ÎÎÎÎÎÏÏÏÏÏÌÌÌÌÌÌ */ + $"EEED F3FF FFFF F2EE EFEF EFEF EFEF EFEF" /* ÓÌÛˇˇˇÚÓÔÔÔÔÔÔÔÔ */ + $"EFEF EFEF EFEF EFEF EFEF EFEF EFEF EFEF" /* ÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔ */ + $"EEEE EEEE EEEE EEED EDED EDED EDEC ECEC" /* ÓÓÓÓÓÓÓÌÌÌÌÌÌÏÏÏ */ + $"ECEC EBEB EBEB EBEC E127 0000 0000 0000" /* ÏÏÎÎÎÎÎÏ·'...... */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0031 B9E6 E6E5 E6E6" /* .........1πÊÊÂÊÊ */ + $"E6E6 E7E7 E7E7 E8E8 E8E9 E9E9 E9EA EAEA" /* ÊÊÁÁÁÁËËËÈÈÈÈÍÍÍ */ + $"EAEA EBEB EBEB ECEC ECEC ECED EDED EDED" /* ÍÍÎÎÎÎÏÏÏÏÏÌÌÌÌÌ */ + $"EDED EEFA FFFF F3ED EEEE EEEF EFEF EFEF" /* ÌÌÓ˙ˇˇÛÌÓÓÓÔÔÔÔÔ */ + $"EFEF EFEF EFEF EFEF EFEF EFEF EFEE EEEE" /* ÔÔÔÔÔÔÔÔÔÔÔÔÔÓÓÓ */ + $"EEEE EEEE EEEE EDED EDED EDED ECEC ECEC" /* ÓÓÓÓÓÓÌÌÌÌÌÌÏÏÏÏ */ + $"ECEB EBEB EBEB EAEA F379 0000 0000 0000" /* ÏÎÎÎÎÎÍÍÛy...... */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 1E9C E3E7 E6E6" /* ...........ú„ÁÊÊ */ + $"E6E6 E6E7 E7E7 E7E7 E8E8 E9E9 E9E9 EAEA" /* ÊÊÊÁÁÁÁÁËËÈÈÈÈÍÍ */ + $"EAEA EAEB EBEB EBEB ECEC ECEC ECED EDED" /* ÍÍÍÎÎÎÎÎÏÏÏÏÏÌÌÌ */ + $"EDED EDF1 FEFF F5ED EEEE EEEE EEEE EEEF" /* ÌÌÌÒ˛ˇıÌÓÓÓÓÓÓÓÔ */ + $"EFEF EFEF EFEF EFEF EFEF EEEE EEEE EEEE" /* ÔÔÔÔÔÔÔÔÔÔÓÓÓÓÓÓ */ + $"EEEE EEEE EEED EDED EDED EDEC ECEC ECEC" /* ÓÓÓÓÓÌÌÌÌÌÌÏÏÏÏÏ */ + $"ECEB EBEB EBEB EAEA EFC7 0F00 0000 0000" /* ÏÎÎÎÎÎÍÍÔ«...... */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 000A 79D8 E6E6" /* ...........¬yÿÊÊ */ + $"E6E6 E6E6 E7E7 E7E7 E7E8 E8E9 E9E9 E9E9" /* ÊÊÊÊÁÁÁÁÁËËÈÈÈÈÈ */ + $"EAEA EAEA EBEB EBEB EBEC ECEC ECEC ECED" /* ÍÍÍÍÎÎÎÎÎÏÏÏÏÏÏÌ */ + $"EDED EDED F2FF F8ED EEEE EEEE EEEE EEEE" /* ÌÌÌÌÚˇ¯ÌÓÓÓÓÓÓÓÓ */ + $"EEEE EEEE EEEE EEEE EEEE EEEE EEEE EEEE" /* ÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓ */ + $"EEEE EEED EDED EDED EDED ECEC ECEC ECEC" /* ÓÓÓÌÌÌÌÌÌÌÏÏÏÏÏÏ */ + $"EBEB EBEB EBEA EAEA EAEF 4E00 0000 0000" /* ÎÎÎÎÎÍÍÍÍÔN..... */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 004D BFE5" /* .............Mø */ + $"E6E7 E6E6 E6E7 E7E7 E7E7 E8E8 E8E9 E9E9" /* ÊÁÊÊÊÁÁÁÁÁËËËÈÈÈ */ + $"E9EA EAEA EAEA EBEB EBEB EBEC ECEC ECEC" /* ÈÍÍÍÍÍÎÎÎÎÎÏÏÏÏÏ */ + $"ECED EDED EDFB F9ED EDEE EEEE EEEE EEEE" /* ÏÌÌÌÌ˚˘ÌÌÓÓÓÓÓÓÓ */ + $"EEEE EEEE EEEE EEEE EEEE EEEE EEEE EEEE" /* ÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓ */ + $"EEED EDED EDED EDED EDEC ECEC ECEC ECEB" /* ÓÌÌÌÌÌÌÌÌÏÏÏÏÏÏÎ */ + $"EBEB EBEB EAEA EAEA EAF1 A303 0000 0000" /* ÎÎÎÎÍÍÍÍÍÒ£..... */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 2195" /* ..............!ï */ + $"DCE5 E7E6 E6E6 E7E7 E7E7 E7E8 E8E8 E9E9" /* ‹ÂÁÊÊÊÁÁÁÁÁËËËÈÈ */ + $"E9E9 EAEA EAEA EAEB EBEB EBEB ECEC ECEC" /* ÈÈÍÍÍÍÍÎÎÎÎÎÏÏÏÏ */ + $"ECEC ECED ECF7 FCED EDED EDED EEEE EEEE" /* ÏÏÏÌϘ¸ÌÌÌÌÌÓÓÓÓ */ + $"EEEE EEEE EEEE EEEE EEEE EEEE EEEE EEED" /* ÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÌ */ + $"EDED EDED EDED EDED ECEC ECEC ECEC ECEB" /* ÌÌÌÌÌÌÌÌÏÏÏÏÏÏÏÎ */ + $"EBEB EBEB EAEA EAEA E9EB E12A 0000 0000" /* ÎÎÎÎÍÍÍÍÈη*.... */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0004" /* ................ */ + $"57BF E3E7 E7E6 E6E7 E7E7 E7E7 E8E8 E8E9" /* Wø„ÁÁÊÊÁÁÁÁÁËËËÈ */ + $"E9E9 E9E9 EAEA EAEA EBEB EBEB EBEB ECEC" /* ÈÈÈÈÍÍÍÍÎÎÎÎÎÎÏÏ */ + $"ECEC ECEC ECEF FDEF EDED EDED EDED EDED" /* ÏÏÏÏÏÔ˝ÔÌÌÌÌÌÌÌÌ */ + $"EDEE EEEE EEEE EEEE EEEE EEED EDED EDED" /* ÌÓÓÓÓÓÓÓÓÓÓÌÌÌÌÌ */ + $"EDEE EEED EDED EDEC ECEC ECEC ECEC EBEB" /* ÌÓÓÌÌÌÌÏÏÏÏÏÏÏÎÎ */ + $"EBEB EBEA EAEA EAEA E9E9 F27A 0100 0000" /* ÎÎÎÍÍÍÍÍÈÈÚz.... */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"001E 84D1 E6E7 E7E6 E7E7 E7E7 E7E8 E8E8" /* ..Ñ—ÊÁÁÊÁÁÁÁÁËËË */ + $"E9E9 E9E9 E9EA EAEA EAEA EBEB EBEB EBEB" /* ÈÈÈÈÈÍÍÍÍÍÎÎÎÎÎÎ */ + $"ECEC ECEC ECEC F9EF EDED EDED EDED EDED" /* ÏÏÏÏÏÏ˘ÔÌÌÌÌÌÌÌÌ */ + $"EDED EDED EDED EDED EDED EDED EDED EDEE" /* ÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÓ */ + $"EEEB E6ED EDEC ECEC ECEC ECEC ECEB EBEB" /* ÓÎÊÌÌÏÏÏÏÏÏÏÏÎÎÎ */ + $"EBEB EAEA EAEA EAE9 E9E9 EEC8 0F00 0000" /* ÎÎÍÍÍÍÍÈÈÈÓ».... */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0038 9DD9 E6E7 E7E7 E7E7 E7E7 E8E8" /* ...8ùŸÊÁÁÁÁÁÁÁËË */ + $"E8E8 E9E9 E9E9 EAEA EAEA EAEA EBEB EBEB" /* ËËÈÈÈÈÍÍÍÍÍÍÎÎÎÎ */ + $"EBEB ECEC ECEB F0EF ECEC EDED EDED EDED" /* ÎÎÏÏÏÎÔÏÏÌÌÌÌÌÌ */ + $"EDED EDED EDED EDED EDED EDED EDEE EEED" /* ÌÌÌÌÌÌÌÌÌÌÌÌÌÓÓÌ */ + $"E09C 71EA EDEC ECEC ECEC ECEB EBEB EBEB" /* ‡úqÍÌÏÏÏÏÏÏÎÎÎÎÎ */ + $"EBEB EAEA EAEA EAE9 E9E9 E9EE 4F00 0000" /* ÎÎÍÍÍÍÍÈÈÈÈÓO... */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0548 A5DA E5E7 E8E8 E7E7 E7E7" /* .....H•⁄ÂÁËËÁÁÁÁ */ + $"E8E8 E8E9 E9E9 E9E9 EAEA EAEA EAEB EBEB" /* ËËËÈÈÈÈÈÍÍÍÍÍÎÎÎ */ + $"EBEB EBEB ECEC ECEC ECEC ECEC ECEC EDED" /* ÎÎÎÎÏÏÏÏÏÏÏÏÏÏÌÌ */ + $"EDED EDED EDED EDED EDED EDEE EFEC E2AD" /* ÌÌÌÌÌÌÌÌÌÌÌÓÔÏ‚≠ */ + $"4B04 06C2 F0EC ECEC ECEC EBEB EBEB EBEB" /* K..¬ÏÏÏÏÏÎÎÎÎÎÎ */ + $"EBEA EAEA EAEA E9E9 E9E9 E9F0 A504 0000" /* ÎÍÍÍÍÍÈÈÈÈÈ•... */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 074B 9FD5 E4E6 E9E8 E8E7" /* .......Kü’‰ÊÈËËÁ */ + $"E7E8 E8E8 E9E9 E9E9 E9EA EAEA EAEA EAEB" /* ÁËËËÈÈÈÈÈÍÍÍÍÍÍÎ */ + $"EBEB EBEB EBEB ECEC ECEC ECEC ECEC ECEC" /* ÎÎÎÎÎÎÏÏÏÏÏÏÏÏÏÏ */ + $"ECEC ECEC EDED EDED EEEE EDEB DAA3 4F09" /* ÏÏÏÏÌÌÌÌÓÓÌÎ⁄£O∆ */ + $"0000 0072 F4EC ECEC ECEB EBEB EBEB EBEB" /* ...rÙÏÏÏÏÎÎÎÎÎÎÎ */ + $"EAEA EAEA EAE9 E9E9 E9E9 E8EA E12B 0000" /* ÍÍÍÍÍÈÈÈÈÈËÍ·+.. */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 033A 8CC6 E0E6 E7E9" /* .........:å∆‡ÊÁÈ */ + $"E8E8 E8E8 E8E8 E9E9 E9E9 E9EA EAEA EAEA" /* ËËËËËËÈÈÈÈÈÍÍÍÍÍ */ + $"EAEB EBEB EBEB EBEB EBEC ECEC ECEC ECEC" /* ÍÎÎÎÎÎÎÎÎÏÏÏÏÏÏÏ */ + $"ECEC ECEC ECED EDED EBE6 CD92 3C04 0000" /* ÏÏÏÏÏÌÌÌÎÊÕí<... */ + $"0000 0023 DFEF ECEB EBEB EBEB EBEB EAEA" /* ...#flÔÏÎÎÎÎÎÎÎÍÍ */ + $"EAEA EAEA E9E9 E9E9 E9E9 E8E8 F17C 0100" /* ÍÍÍÍÈÈÈÈÈÈËËÒ|.. */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0020 64A7 D1E2" /* ........... dß—‚ */ + $"E6E7 E9E8 E8E8 E8E9 E9E9 E9E9 E9EA EAEA" /* ÊÁÈËËËËÈÈÈÈÈÈÍÍÍ */ + $"EAEA EAEB EBEB EBEB EBEB EBEC ECEC ECEC" /* ÍÍÍÎÎÎÎÎÎÎÎÏÏÏÏÏ */ + $"ECED EDED EDEB E8D8 AB67 2300 0000 0000" /* ÏÌÌÌÌÎËÿ´g#..... */ + $"0000 0001 9FF3 EBEB EBEB EBEB EBEA EAEA" /* ....üÛÎÎÎÎÎÎÎÍÍÍ */ + $"EAEA EAEA E9E9 E9E9 E9E8 E8E8 EDC9 1000" /* ÍÍÍÍÈÈÈÈÈËËËÌ….. */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0006 3070" /* ..............0p */ + $"A8CC DEE5 E8E8 E9E9 E8E9 E9E9 E9E9 EAEA" /* ®ÃfiÂËËÈÈËÈÈÈÈÈÍÍ */ + $"EAEA EAEA EAEB EBEB EBEB EBEB ECEC ECEC" /* ÍÍÍÍÍÎÎÎÎÎÎÎÏÏÏÏ */ + $"EDEB EAE5 D1A9 7136 0700 0000 0000 0000" /* ÌÎÍ—©q6........ */ + $"0000 0000 48ED EBEB EBEB EBEB EAEA EAEA" /* ....HÌÎÎÎÎÎÎÍÍÍÍ */ + $"EAEA EAE9 E9E9 E9E9 E8E8 E8E8 E8ED 5200" /* ÍÍÍÈÈÈÈÈËËËËËÌR. */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0625 588B B1CE DCE3 E6E8 E9E9 E9EA EAE9" /* .%X㱌‹„ÊËÈÈÈÍÍÈ */ + $"EAEA EAEA EAEA EAEB ECEB EBEB EAE9 E7E1" /* ÍÍÍÍÍÍÍÎÏÎÎÎÍÈÁ· */ + $"D0B4 8C5C 2805 0000 0000 0000 0000 0000" /* –¥å\(........... */ + $"0000 0000 0DC4 F0EB EBEB EAEA EAEA EAEA" /* .....ƒÎÎÎÍÍÍÍÍÍ */ + $"EAEA E9E9 E9E9 E9E9 E8E8 E8E8 E7EF A704" /* ÍÍÈÈÈÈÈÈËËËËÁÔß. */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0921 4260 7D96 A7B6 C3CA D2DC" /* ....∆!B`}ñß∂√ “‹ */ + $"E1E5 E8E9 E3E0 DCD5 CAC2 B8AB 957C 6043" /* ·ÂËÈ„‡‹’ ¬∏´ï|`C */ + $"2209 0000 0000 0000 0000 0000 0000 0000" /* "∆.............. */ + $"0000 0000 006D F1EB EBEA EAEA EAEA EAEA" /* .....mÒÎÎÍÍÍÍÍÍÍ */ + $"EAE9 E9E9 E9E9 E9E8 E8E8 E8E7 E7E8 E435" /* ÍÈÈÈÈÈÈËËËËÁÁˉ5 */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0006 101E 2E3A 5072" /* .............:Pr */ + $"848F 9B99 8A7B 6E56 392A 1D12 0500 0000" /* Ñèõôä{nV9*...... */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0024 A1A1 A0A0 A0A0 A0A0 A09F" /* .....$°°†††††††ü */ + $"9F9F 9F9F 9F9F 9F9F 9F9F 9F9E 9E9E A548" /* üüüüüüüüüüüûûû•H */ + $"0000 00" /* ... */ +}; + diff --git a/app/src/main/assets/roms/qemu_logo.svg b/app/src/main/assets/roms/qemu_logo.svg new file mode 100644 index 0000000..07b5b51 --- /dev/null +++ b/app/src/main/assets/roms/qemu_logo.svg @@ -0,0 +1,1010 @@ + + + + + Kew the Angry Emu + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + Kew the Angry Emu + + + Benoît Canet + + + + + CC BY 3.0 + + + + + QEMU Community + + + 2012-02-15 + + + + QEMU logo + QEMU mascot + + + http://lists.gnu.org/archive/html/qemu-devel/2012-02/msg01961.html + + + + + + + + + + + + + + + + + + EMU + + diff --git a/app/src/main/assets/roms/s390-ccw.img b/app/src/main/assets/roms/s390-ccw.img new file mode 100644 index 0000000..3074686 Binary files /dev/null and b/app/src/main/assets/roms/s390-ccw.img differ diff --git a/app/src/main/assets/roms/s390-netboot.img b/app/src/main/assets/roms/s390-netboot.img new file mode 100644 index 0000000..d9c3196 Binary files /dev/null and b/app/src/main/assets/roms/s390-netboot.img differ diff --git a/app/src/main/assets/roms/sgabios.bin b/app/src/main/assets/roms/sgabios.bin new file mode 100644 index 0000000..6308f2e Binary files /dev/null and b/app/src/main/assets/roms/sgabios.bin differ diff --git a/app/src/main/assets/roms/slof.bin b/app/src/main/assets/roms/slof.bin new file mode 100644 index 0000000..448dcad Binary files /dev/null and b/app/src/main/assets/roms/slof.bin differ diff --git a/app/src/main/assets/roms/u-boot-sam460-20100605.bin b/app/src/main/assets/roms/u-boot-sam460-20100605.bin new file mode 100644 index 0000000..e17de77 Binary files /dev/null and b/app/src/main/assets/roms/u-boot-sam460-20100605.bin differ diff --git a/app/src/main/assets/roms/vgabios-ati.bin b/app/src/main/assets/roms/vgabios-ati.bin new file mode 100644 index 0000000..3dbfe53 Binary files /dev/null and b/app/src/main/assets/roms/vgabios-ati.bin differ diff --git a/app/src/main/assets/roms/vgabios-bochs-display.bin b/app/src/main/assets/roms/vgabios-bochs-display.bin new file mode 100644 index 0000000..ca4c3db Binary files /dev/null and b/app/src/main/assets/roms/vgabios-bochs-display.bin differ diff --git a/app/src/main/assets/roms/vgabios-cirrus.bin b/app/src/main/assets/roms/vgabios-cirrus.bin new file mode 100644 index 0000000..b8ee1fe Binary files /dev/null and b/app/src/main/assets/roms/vgabios-cirrus.bin differ diff --git a/app/src/main/assets/roms/vgabios-qxl.bin b/app/src/main/assets/roms/vgabios-qxl.bin new file mode 100644 index 0000000..9829cd1 Binary files /dev/null and b/app/src/main/assets/roms/vgabios-qxl.bin differ diff --git a/app/src/main/assets/roms/vgabios-ramfb.bin b/app/src/main/assets/roms/vgabios-ramfb.bin new file mode 100644 index 0000000..12dcb8e Binary files /dev/null and b/app/src/main/assets/roms/vgabios-ramfb.bin differ diff --git a/app/src/main/assets/roms/vgabios-stdvga.bin b/app/src/main/assets/roms/vgabios-stdvga.bin new file mode 100644 index 0000000..68fe2fe Binary files /dev/null and b/app/src/main/assets/roms/vgabios-stdvga.bin differ diff --git a/app/src/main/assets/roms/vgabios-virtio.bin b/app/src/main/assets/roms/vgabios-virtio.bin new file mode 100644 index 0000000..60ce81d Binary files /dev/null and b/app/src/main/assets/roms/vgabios-virtio.bin differ diff --git a/app/src/main/assets/roms/vgabios-vmware.bin b/app/src/main/assets/roms/vgabios-vmware.bin new file mode 100644 index 0000000..b75a351 Binary files /dev/null and b/app/src/main/assets/roms/vgabios-vmware.bin differ diff --git a/app/src/main/assets/roms/vgabios.bin b/app/src/main/assets/roms/vgabios.bin new file mode 100644 index 0000000..410436f Binary files /dev/null and b/app/src/main/assets/roms/vgabios.bin differ diff --git a/app/src/main/java/android/androidVNC/AbstractBitmapData.java b/app/src/main/java/android/androidVNC/AbstractBitmapData.java new file mode 100644 index 0000000..d18f634 --- /dev/null +++ b/app/src/main/java/android/androidVNC/AbstractBitmapData.java @@ -0,0 +1,203 @@ +/** + * Copyright (C) 2009 Michael A. MacDonald + */ +package android.androidVNC; + +import java.io.IOException; + +import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.graphics.Rect; +import android.widget.ImageView; + +/** + * Abstract interface between the VncCanvas and the bitmap and pixel data + * buffers that actually contain the data. This allows for implementations that + * use smaller bitmaps or buffers to save memory. + * + * @author Michael A. MacDonald + * + */ +abstract class AbstractBitmapData { + int framebufferwidth; + int framebufferheight; + int bitmapwidth; + int bitmapheight; + RfbProto rfb; + Bitmap mbitmap; + int bitmapPixels[]; + Canvas memGraphics; + boolean waitingForInput; + VncCanvas vncCanvas; + private AbstractBitmapDrawable drawable; + + AbstractBitmapData(RfbProto p, VncCanvas c) { + rfb = p; + vncCanvas = c; + framebufferwidth = rfb.framebufferWidth; + framebufferheight = rfb.framebufferHeight; + } + + synchronized void doneWaiting() { + waitingForInput = false; + } + + final void invalidateMousePosition() { + if (vncCanvas.connection.getUseLocalCursor()) { + if (drawable == null) + drawable = createDrawable(); + drawable.setCursorRect(vncCanvas.mouseX, vncCanvas.mouseY); + vncCanvas.invalidate(drawable.cursorRect); + } + } + + /** + * + * @return The smallest scale supported by the implementation; the scale at + * which the bitmap would be smaller than the screen + */ + float getMinimumScale() { + double scale = 0.75; + int displayWidth = vncCanvas.getWidth(); + int displayHeight = vncCanvas.getHeight(); + for (; scale >= 0; scale -= 0.25) { + if (scale * bitmapwidth < displayWidth + || scale * bitmapheight < displayHeight) + break; + } + return (float) (scale + 0.25); + } + + /** + * Send a request through the protocol to get the data for the currently + * held bitmap + * + * @param incremental + * True if we want incremental update; false for full update + */ + abstract void writeFullUpdateRequest(boolean incremental) + throws IOException; + + /** + * Determine if a rectangle in full-frame coordinates can be drawn in the + * existing buffer + * + * @param x + * Top left x + * @param y + * Top left y + * @param w + * width (pixels) + * @param h + * height (pixels) + * @return True if entire rectangle fits into current screen buffer, false + * otherwise + */ + abstract boolean validDraw(int x, int y, int w, int h); + + /** + * Return an offset in the bitmapPixels array of a point in full-frame + * coordinates + * + * @param x + * @param y + * @return Offset in bitmapPixels array of color data for that point + */ + abstract int offset(int x, int y); + + /** + * Update pixels in the bitmap with data from the bitmapPixels array, + * positioned in full-frame coordinates + * + * @param x + * Top left x + * @param y + * Top left y + * @param w + * width (pixels) + * @param h + * height (pixels) + */ + abstract void updateBitmap(int x, int y, int w, int h); + + /** + * Create drawable appropriate for this data + * + * @return drawable + */ + abstract AbstractBitmapDrawable createDrawable(); + + /** + * Call in UI thread; tell ImageView we've changed + * + * @param v + * ImageView displaying bitmap data + */ + void updateView(ImageView v) { + if (drawable == null) + drawable = createDrawable(); + v.setImageDrawable(drawable); + v.invalidate(); + } + + /** + * Copy a rectangle from one part of the bitmap to another + * + * @param src + * Rectangle in full-frame coordinates to be copied + * @param dest + * Destination rectangle in full-frame coordinates + * @param paint + * Paint specifier + */ + abstract void copyRect(Rect src, Rect dest, Paint paint); + + /** + * Draw a rectangle in the bitmap with coordinates given in full frame + * + * @param x + * Top left x + * @param y + * Top left y + * @param w + * width (pixels) + * @param h + * height (pixels) + * @param paint + * How to draw + */ + abstract void drawRect(int x, int y, int w, int h, Paint paint); + + /** + * Scroll position has changed. + *

+ * This method is called in the UI thread-- it updates internal status, but + * does not change the bitmap data or send a network request until + * syncScroll is called + * + * @param newx + * Position of left edge of visible part in full-frame + * coordinates + * @param newy + * Position of top edge of visible part in full-frame coordinates + */ + abstract void scrollChanged(int newx, int newy); + + /** + * Sync scroll -- called from network thread; copies scroll changes from UI + * to network state + */ + abstract void syncScroll(); + + /** + * Release resources + */ + void dispose() { + if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH) + if (mbitmap != null) + mbitmap.recycle(); + memGraphics = null; + bitmapPixels = null; + } +} diff --git a/app/src/main/java/android/androidVNC/AbstractBitmapDrawable.java b/app/src/main/java/android/androidVNC/AbstractBitmapDrawable.java new file mode 100644 index 0000000..a311cce --- /dev/null +++ b/app/src/main/java/android/androidVNC/AbstractBitmapDrawable.java @@ -0,0 +1,100 @@ +/** + * Copyright (C) 2009 Michael A. MacDonald + */ +package android.androidVNC; + +import android.graphics.Canvas; +import android.graphics.Paint; +import android.graphics.PixelFormat; +import android.graphics.Rect; +import android.graphics.drawable.DrawableContainer; + +/** + * @author Michael A. MacDonald + * + */ +public class AbstractBitmapDrawable extends DrawableContainer { + Rect cursorRect; + Rect clipRect; + + AbstractBitmapData data; + + static final Paint _defaultPaint; + static final Paint _whitePaint; + static final Paint _blackPaint; + + static { + _defaultPaint = new Paint(); + _whitePaint = new Paint(); + _whitePaint.setColor(0xffffffff); + _blackPaint = new Paint(); + _blackPaint.setColor(0xff000000); + } + + AbstractBitmapDrawable(AbstractBitmapData data) + { + this.data = data; + cursorRect = new Rect(); + clipRect = new Rect(); + } + + void draw(Canvas canvas, int xoff, int yoff) + { + canvas.drawBitmap(data.mbitmap, xoff, yoff, _defaultPaint); + if(data.vncCanvas.connection.getUseLocalCursor()) + { + setCursorRect(data.vncCanvas.mouseX, data.vncCanvas.mouseY); + clipRect.set(cursorRect); + if (canvas.clipRect(cursorRect)) + { + drawCursor(canvas); + } + } + } + + void drawCursor(Canvas canvas) + { + canvas.drawRect(cursorRect,_whitePaint); + canvas.drawRect((float)cursorRect.left + 1, (float)cursorRect.top + 1, (float)cursorRect.right - 1, (float)cursorRect.bottom - 1, _blackPaint); + } + + void setCursorRect(int mouseX, int mouseY) + { + cursorRect.left = mouseX - 2; + cursorRect.right = cursorRect.left + 4; + cursorRect.top = mouseY - 2; + cursorRect.bottom = cursorRect.top + 4; + } + + /* (non-Javadoc) + * @see android.graphics.drawable.DrawableContainer#getIntrinsicHeight() + */ + @Override + public int getIntrinsicHeight() { + return data.framebufferheight; + } + + /* (non-Javadoc) + * @see android.graphics.drawable.DrawableContainer#getIntrinsicWidth() + */ + @Override + public int getIntrinsicWidth() { + return data.framebufferwidth; + } + + /* (non-Javadoc) + * @see android.graphics.drawable.DrawableContainer#getOpacity() + */ + @Override + public int getOpacity() { + return PixelFormat.OPAQUE; + } + + /* (non-Javadoc) + * @see android.graphics.drawable.DrawableContainer#isStateful() + */ + @Override + public boolean isStateful() { + return false; + } +} diff --git a/app/src/main/java/android/androidVNC/AbstractGestureInputHandler.java b/app/src/main/java/android/androidVNC/AbstractGestureInputHandler.java new file mode 100644 index 0000000..8ed2e70 --- /dev/null +++ b/app/src/main/java/android/androidVNC/AbstractGestureInputHandler.java @@ -0,0 +1,88 @@ +/** + * Copyright (C) 2009 Michael A. MacDonald + */ +package android.androidVNC; + +import android.view.GestureDetector; +import android.view.MotionEvent; + +/** + * An AbstractInputHandler that uses GestureDetector to detect standard gestures in touch events + * + * @author Michael A. MacDonald + */ +abstract class AbstractGestureInputHandler extends GestureDetector.SimpleOnGestureListener implements AbstractInputHandler { + protected GestureDetector gestures = new GestureDetector(this); + private VncCanvasActivity activity; + + float xInitialFocus; + float yInitialFocus; + boolean inScaling; + + private static final String TAG = "AbstractGestureInputHandler"; + + AbstractGestureInputHandler(VncCanvasActivity c) + { + activity = c; + gestures.setOnDoubleTapListener(this); + } + + @Override + public boolean onTouchEvent(MotionEvent evt) { + //MK + if(evt.getAction()==MotionEvent.ACTION_CANCEL) + return true; + + return gestures.onTouchEvent(evt); + } + + /* (non-Javadoc) + * @see com.antlersoft.android.bc.OnScaleGestureListener#onScale(com.antlersoft.android.bc.IBCScaleGestureDetector) + */ +// @Override +// public boolean onScale(IBCScaleGestureDetector detector) { +// boolean consumed = true; +// //if (detector.) +// //Log.i(TAG,"Focus("+detector.getFocusX()+","+detector.getFocusY()+") scaleFactor = "+detector.getScaleFactor()); +// // Calculate focus shift +// float fx = detector.getFocusX(); +// float fy = detector.getFocusY(); +// double xfs = fx - xInitialFocus; +// double yfs = fy - yInitialFocus; +// double fs = Math.sqrt(xfs * xfs + yfs * yfs); +// if (Math.abs(1.0 - detector.getScaleFactor())<0.02) +// consumed = false; +// if (fs * 2< Math.abs(detector.getCurrentSpan() - detector.getPreviousSpan())) +// { +// inScaling = true; +// if (consumed) +// { +// //Log.i(TAG,"Adjust scaling "+detector.getScaleFactor()); +// if (activity.vncCanvas != null && activity.vncCanvas.scaling != null) +// activity.vncCanvas.scaling.adjust(activity, detector.getScaleFactor(), fx, fy); +// } +// } +// return consumed; +// } +// +// /* (non-Javadoc) +// * @see com.antlersoft.android.bc.OnScaleGestureListener#onScaleBegin(com.antlersoft.android.bc.IBCScaleGestureDetector) +// */ +// @Override +// public boolean onScaleBegin(IBCScaleGestureDetector detector) { +// xInitialFocus = detector.getFocusX(); +// yInitialFocus = detector.getFocusY(); +// inScaling = false; +// //Log.i(TAG,"scale begin ("+xInitialFocus+","+yInitialFocus+")"); +// return true; +// } +// +// /* (non-Javadoc) +// * @see com.antlersoft.android.bc.OnScaleGestureListener#onScaleEnd(com.antlersoft.android.bc.IBCScaleGestureDetector) +// */ +// @Override +// public void onScaleEnd(IBCScaleGestureDetector detector) { +// //Log.i(TAG,"scale end"); +// inScaling = false; +// } +} diff --git a/app/src/main/java/android/androidVNC/AbstractInputHandler.java b/app/src/main/java/android/androidVNC/AbstractInputHandler.java new file mode 100644 index 0000000..47e49dc --- /dev/null +++ b/app/src/main/java/android/androidVNC/AbstractInputHandler.java @@ -0,0 +1,54 @@ +/** + * Copyright (C) 2009 Michael A. MacDonald + */ +package android.androidVNC; + +import android.view.KeyEvent; +import android.view.MotionEvent; + +/** + * The VncCanvasActivity has several different ways of handling input from the touchscreen, + * keyboard, buttons and trackball. These will be represented by different implementations + * of this interface. Putting the different modes in different classes + * will keep the logic clean. The relevant Activity callbacks in VncCanvasActivity + * are forwarded to methods in AbstractInputHandler. + *

+ * It is expected that the implementations will be contained within + * VncCanvasActivity, so they can do things like super.VncCanvasActivity.onXXX to invoke + * default behavior. + * @author Michael A. MacDonald + * + */ +public interface AbstractInputHandler { + /** + * Note: Menu key code is handled before this is called + * @see android.app.Activity#onKeyDown(int keyCode, KeyEvent evt) + */ + boolean onKeyDown(int keyCode, KeyEvent evt); + /** + * Note: Menu key code is handled before this is called + * @see android.app.Activity#onKeyUp(int keyCode, KeyEvent evt) + */ + boolean onKeyUp(int keyCode, KeyEvent evt); + /* (non-Javadoc) + * @see android.app.Activity#onTrackballEvent(android.view.MotionEvent) + */ + boolean onTrackballEvent( MotionEvent evt); + /* (non-Javadoc) + * @see android.app.Activity#onTrackballEvent(android.view.MotionEvent) + */ + boolean onTouchEvent( MotionEvent evt); + + /** + * Return a user-friendly description for this mode; it will be displayed in a toaster + * when changing modes. + * @return + */ + public CharSequence getHandlerDescription(); + + /** + * Return an internal name for this handler; this name will be stable across language + * and version changes + */ + String getName(); +} diff --git a/app/src/main/java/android/androidVNC/AbstractScaling.java b/app/src/main/java/android/androidVNC/AbstractScaling.java new file mode 100644 index 0000000..f33209d --- /dev/null +++ b/app/src/main/java/android/androidVNC/AbstractScaling.java @@ -0,0 +1,122 @@ +/** + * Copyright (C) 2009 Michael A. MacDonald + */ +package android.androidVNC; + +import android.widget.ImageView; + +import com.vectras.vm.R; + +/** + * @author Michael A. MacDonald + * + * A scaling mode for the VncCanvas; based on ImageView.ScaleType + */ +public abstract class AbstractScaling { + private static final int scaleModeIds[] = { R.id.itemFitToScreen, R.id.itemOneToOne, R.id.itemZoomable }; + + private static AbstractScaling[] scalings; + + public static AbstractScaling getById(int id) + { + if ( scalings==null) + { + scalings=new AbstractScaling[scaleModeIds.length]; + } + for ( int i=0; i(64, (float)0.25); + orderedList = new Vector(32, 8); + } + + public void add(CapabilityInfo capinfo) { + Integer key = new Integer(capinfo.getCode()); + infoMap.put(key, capinfo); + } + + public void add(int code, String vendor, String name, String desc) { + Integer key = new Integer(code); + infoMap.put(key, new CapabilityInfo(code, vendor, name, desc)); + } + + public boolean isKnown(int code) { + return infoMap.containsKey(new Integer(code)); + } + + public CapabilityInfo getInfo(int code) { + return (CapabilityInfo)infoMap.get(new Integer(code)); + } + + public String getDescription(int code) { + CapabilityInfo capinfo = (CapabilityInfo)infoMap.get(new Integer(code)); + if (capinfo == null) + return null; + + return capinfo.getDescription(); + } + + public boolean enable(CapabilityInfo other) { + Integer key = new Integer(other.getCode()); + CapabilityInfo capinfo = (CapabilityInfo)infoMap.get(key); + if (capinfo == null) + return false; + + boolean enabled = capinfo.enableIfEquals(other); + if (enabled) + orderedList.addElement(key); + + return enabled; + } + + public boolean isEnabled(int code) { + CapabilityInfo capinfo = (CapabilityInfo)infoMap.get(new Integer(code)); + if (capinfo == null) + return false; + + return capinfo.isEnabled(); + } + + public int numEnabled() { + return orderedList.size(); + } + + public int getByOrder(int idx) { + int code; + try { + code = ((Integer)orderedList.elementAt(idx)).intValue(); + } catch (ArrayIndexOutOfBoundsException e) { + code = 0; + } + return code; + } + + // Protected data + + protected Hashtable infoMap; + protected Vector orderedList; +} + diff --git a/app/src/main/java/android/androidVNC/ColorModel256.java b/app/src/main/java/android/androidVNC/ColorModel256.java new file mode 100644 index 0000000..f759fe3 --- /dev/null +++ b/app/src/main/java/android/androidVNC/ColorModel256.java @@ -0,0 +1,266 @@ +package android.androidVNC; + +public class ColorModel256 { + + public final static int [] colors; + + static { + colors = new int[256]; + colors[0]=0xff000000; + colors[1]=0xff240000; + colors[2]=0xff490000; + colors[3]=0xff6d0000; + colors[4]=0xff920000; + colors[5]=0xffb60000; + colors[6]=0xffdb0000; + colors[7]=0xffff0000; + colors[8]=0xff002400; + colors[9]=0xff242400; + colors[10]=0xff492400; + colors[11]=0xff6d2400; + colors[12]=0xff922400; + colors[13]=0xffb62400; + colors[14]=0xffdb2400; + colors[15]=0xffff2400; + colors[16]=0xff004900; + colors[17]=0xff244900; + colors[18]=0xff494900; + colors[19]=0xff6d4900; + colors[20]=0xff924900; + colors[21]=0xffb64900; + colors[22]=0xffdb4900; + colors[23]=0xffff4900; + colors[24]=0xff006d00; + colors[25]=0xff246d00; + colors[26]=0xff496d00; + colors[27]=0xff6d6d00; + colors[28]=0xff926d00; + colors[29]=0xffb66d00; + colors[30]=0xffdb6d00; + colors[31]=0xffff6d00; + colors[32]=0xff009200; + colors[33]=0xff249200; + colors[34]=0xff499200; + colors[35]=0xff6d9200; + colors[36]=0xff929200; + colors[37]=0xffb69200; + colors[38]=0xffdb9200; + colors[39]=0xffff9200; + colors[40]=0xff00b600; + colors[41]=0xff24b600; + colors[42]=0xff49b600; + colors[43]=0xff6db600; + colors[44]=0xff92b600; + colors[45]=0xffb6b600; + colors[46]=0xffdbb600; + colors[47]=0xffffb600; + colors[48]=0xff00db00; + colors[49]=0xff24db00; + colors[50]=0xff49db00; + colors[51]=0xff6ddb00; + colors[52]=0xff92db00; + colors[53]=0xffb6db00; + colors[54]=0xffdbdb00; + colors[55]=0xffffdb00; + colors[56]=0xff00ff00; + colors[57]=0xff24ff00; + colors[58]=0xff49ff00; + colors[59]=0xff6dff00; + colors[60]=0xff92ff00; + colors[61]=0xffb6ff00; + colors[62]=0xffdbff00; + colors[63]=0xffffff00; + colors[64]=0xff000055; + colors[65]=0xff240055; + colors[66]=0xff490055; + colors[67]=0xff6d0055; + colors[68]=0xff920055; + colors[69]=0xffb60055; + colors[70]=0xffdb0055; + colors[71]=0xffff0055; + colors[72]=0xff002455; + colors[73]=0xff242455; + colors[74]=0xff492455; + colors[75]=0xff6d2455; + colors[76]=0xff922455; + colors[77]=0xffb62455; + colors[78]=0xffdb2455; + colors[79]=0xffff2455; + colors[80]=0xff004955; + colors[81]=0xff244955; + colors[82]=0xff494955; + colors[83]=0xff6d4955; + colors[84]=0xff924955; + colors[85]=0xffb64955; + colors[86]=0xffdb4955; + colors[87]=0xffff4955; + colors[88]=0xff006d55; + colors[89]=0xff246d55; + colors[90]=0xff496d55; + colors[91]=0xff6d6d55; + colors[92]=0xff926d55; + colors[93]=0xffb66d55; + colors[94]=0xffdb6d55; + colors[95]=0xffff6d55; + colors[96]=0xff009255; + colors[97]=0xff249255; + colors[98]=0xff499255; + colors[99]=0xff6d9255; + colors[100]=0xff929255; + colors[101]=0xffb69255; + colors[102]=0xffdb9255; + colors[103]=0xffff9255; + colors[104]=0xff00b655; + colors[105]=0xff24b655; + colors[106]=0xff49b655; + colors[107]=0xff6db655; + colors[108]=0xff92b655; + colors[109]=0xffb6b655; + colors[110]=0xffdbb655; + colors[111]=0xffffb655; + colors[112]=0xff00db55; + colors[113]=0xff24db55; + colors[114]=0xff49db55; + colors[115]=0xff6ddb55; + colors[116]=0xff92db55; + colors[117]=0xffb6db55; + colors[118]=0xffdbdb55; + colors[119]=0xffffdb55; + colors[120]=0xff00ff55; + colors[121]=0xff24ff55; + colors[122]=0xff49ff55; + colors[123]=0xff6dff55; + colors[124]=0xff92ff55; + colors[125]=0xffb6ff55; + colors[126]=0xffdbff55; + colors[127]=0xffffff55; + colors[128]=0xff0000aa; + colors[129]=0xff2400aa; + colors[130]=0xff4900aa; + colors[131]=0xff6d00aa; + colors[132]=0xff9200aa; + colors[133]=0xffb600aa; + colors[134]=0xffdb00aa; + colors[135]=0xffff00aa; + colors[136]=0xff0024aa; + colors[137]=0xff2424aa; + colors[138]=0xff4924aa; + colors[139]=0xff6d24aa; + colors[140]=0xff9224aa; + colors[141]=0xffb624aa; + colors[142]=0xffdb24aa; + colors[143]=0xffff24aa; + colors[144]=0xff0049aa; + colors[145]=0xff2449aa; + colors[146]=0xff4949aa; + colors[147]=0xff6d49aa; + colors[148]=0xff9249aa; + colors[149]=0xffb649aa; + colors[150]=0xffdb49aa; + colors[151]=0xffff49aa; + colors[152]=0xff006daa; + colors[153]=0xff246daa; + colors[154]=0xff496daa; + colors[155]=0xff6d6daa; + colors[156]=0xff926daa; + colors[157]=0xffb66daa; + colors[158]=0xffdb6daa; + colors[159]=0xffff6daa; + colors[160]=0xff0092aa; + colors[161]=0xff2492aa; + colors[162]=0xff4992aa; + colors[163]=0xff6d92aa; + colors[164]=0xff9292aa; + colors[165]=0xffb692aa; + colors[166]=0xffdb92aa; + colors[167]=0xffff92aa; + colors[168]=0xff00b6aa; + colors[169]=0xff24b6aa; + colors[170]=0xff49b6aa; + colors[171]=0xff6db6aa; + colors[172]=0xff92b6aa; + colors[173]=0xffb6b6aa; + colors[174]=0xffdbb6aa; + colors[175]=0xffffb6aa; + colors[176]=0xff00dbaa; + colors[177]=0xff24dbaa; + colors[178]=0xff49dbaa; + colors[179]=0xff6ddbaa; + colors[180]=0xff92dbaa; + colors[181]=0xffb6dbaa; + colors[182]=0xffdbdbaa; + colors[183]=0xffffdbaa; + colors[184]=0xff00ffaa; + colors[185]=0xff24ffaa; + colors[186]=0xff49ffaa; + colors[187]=0xff6dffaa; + colors[188]=0xff92ffaa; + colors[189]=0xffb6ffaa; + colors[190]=0xffdbffaa; + colors[191]=0xffffffaa; + colors[192]=0xff0000ff; + colors[193]=0xff2400ff; + colors[194]=0xff4900ff; + colors[195]=0xff6d00ff; + colors[196]=0xff9200ff; + colors[197]=0xffb600ff; + colors[198]=0xffdb00ff; + colors[199]=0xffff00ff; + colors[200]=0xff0024ff; + colors[201]=0xff2424ff; + colors[202]=0xff4924ff; + colors[203]=0xff6d24ff; + colors[204]=0xff9224ff; + colors[205]=0xffb624ff; + colors[206]=0xffdb24ff; + colors[207]=0xffff24ff; + colors[208]=0xff0049ff; + colors[209]=0xff2449ff; + colors[210]=0xff4949ff; + colors[211]=0xff6d49ff; + colors[212]=0xff9249ff; + colors[213]=0xffb649ff; + colors[214]=0xffdb49ff; + colors[215]=0xffff49ff; + colors[216]=0xff006dff; + colors[217]=0xff246dff; + colors[218]=0xff496dff; + colors[219]=0xff6d6dff; + colors[220]=0xff926dff; + colors[221]=0xffb66dff; + colors[222]=0xffdb6dff; + colors[223]=0xffff6dff; + colors[224]=0xff0092ff; + colors[225]=0xff2492ff; + colors[226]=0xff4992ff; + colors[227]=0xff6d92ff; + colors[228]=0xff9292ff; + colors[229]=0xffb692ff; + colors[230]=0xffdb92ff; + colors[231]=0xffff92ff; + colors[232]=0xff00b6ff; + colors[233]=0xff24b6ff; + colors[234]=0xff49b6ff; + colors[235]=0xff6db6ff; + colors[236]=0xff92b6ff; + colors[237]=0xffb6b6ff; + colors[238]=0xffdbb6ff; + colors[239]=0xffffb6ff; + colors[240]=0xff00dbff; + colors[241]=0xff24dbff; + colors[242]=0xff49dbff; + colors[243]=0xff6ddbff; + colors[244]=0xff92dbff; + colors[245]=0xffb6dbff; + colors[246]=0xffdbdbff; + colors[247]=0xffffdbff; + colors[248]=0xff00ffff; + colors[249]=0xff24ffff; + colors[250]=0xff49ffff; + colors[251]=0xff6dffff; + colors[252]=0xff92ffff; + colors[253]=0xffb6ffff; + colors[254]=0xffdbffff; + colors[255]=0xffffffff; + } +} diff --git a/app/src/main/java/android/androidVNC/ColorModel64.java b/app/src/main/java/android/androidVNC/ColorModel64.java new file mode 100644 index 0000000..7236da8 --- /dev/null +++ b/app/src/main/java/android/androidVNC/ColorModel64.java @@ -0,0 +1,267 @@ +package android.androidVNC; + +public class ColorModel64 { + + public final static int [] colors; + + static { + colors = new int[256]; + colors[0]=0xff000000; + colors[1]=0xff000055; + colors[2]=0xff0000aa; + colors[3]=0xff0000ff; + colors[4]=0xff005500; + colors[5]=0xff005555; + colors[6]=0xff0055aa; + colors[7]=0xff0055ff; + colors[8]=0xff00aa00; + colors[9]=0xff00aa55; + colors[10]=0xff00aaaa; + colors[11]=0xff00aaff; + colors[12]=0xff00ff00; + colors[13]=0xff00ff55; + colors[14]=0xff00ffaa; + colors[15]=0xff00ffff; + colors[16]=0xff550000; + colors[17]=0xff550055; + colors[18]=0xff5500aa; + colors[19]=0xff5500ff; + colors[20]=0xff555500; + colors[21]=0xff555555; + colors[22]=0xff5555aa; + colors[23]=0xff5555ff; + colors[24]=0xff55aa00; + colors[25]=0xff55aa55; + colors[26]=0xff55aaaa; + colors[27]=0xff55aaff; + colors[28]=0xff55ff00; + colors[29]=0xff55ff55; + colors[30]=0xff55ffaa; + colors[31]=0xff55ffff; + colors[32]=0xffaa0000; + colors[33]=0xffaa0055; + colors[34]=0xffaa00aa; + colors[35]=0xffaa00ff; + colors[36]=0xffaa5500; + colors[37]=0xffaa5555; + colors[38]=0xffaa55aa; + colors[39]=0xffaa55ff; + colors[40]=0xffaaaa00; + colors[41]=0xffaaaa55; + colors[42]=0xffaaaaaa; + colors[43]=0xffaaaaff; + colors[44]=0xffaaff00; + colors[45]=0xffaaff55; + colors[46]=0xffaaffaa; + colors[47]=0xffaaffff; + colors[48]=0xffff0000; + colors[49]=0xffff0055; + colors[50]=0xffff00aa; + colors[51]=0xffff00ff; + colors[52]=0xffff5500; + colors[53]=0xffff5555; + colors[54]=0xffff55aa; + colors[55]=0xffff55ff; + colors[56]=0xffffaa00; + colors[57]=0xffffaa55; + colors[58]=0xffffaaaa; + colors[59]=0xffffaaff; + colors[60]=0xffffff00; + colors[61]=0xffffff55; + colors[62]=0xffffffaa; + colors[63]=0xffffffff; + colors[64]=0xff000000; + colors[65]=0xff000055; + colors[66]=0xff0000aa; + colors[67]=0xff0000ff; + colors[68]=0xff005500; + colors[69]=0xff005555; + colors[70]=0xff0055aa; + colors[71]=0xff0055ff; + colors[72]=0xff00aa00; + colors[73]=0xff00aa55; + colors[74]=0xff00aaaa; + colors[75]=0xff00aaff; + colors[76]=0xff00ff00; + colors[77]=0xff00ff55; + colors[78]=0xff00ffaa; + colors[79]=0xff00ffff; + colors[80]=0xff550000; + colors[81]=0xff550055; + colors[82]=0xff5500aa; + colors[83]=0xff5500ff; + colors[84]=0xff555500; + colors[85]=0xff555555; + colors[86]=0xff5555aa; + colors[87]=0xff5555ff; + colors[88]=0xff55aa00; + colors[89]=0xff55aa55; + colors[90]=0xff55aaaa; + colors[91]=0xff55aaff; + colors[92]=0xff55ff00; + colors[93]=0xff55ff55; + colors[94]=0xff55ffaa; + colors[95]=0xff55ffff; + colors[96]=0xffaa0000; + colors[97]=0xffaa0055; + colors[98]=0xffaa00aa; + colors[99]=0xffaa00ff; + colors[100]=0xffaa5500; + colors[101]=0xffaa5555; + colors[102]=0xffaa55aa; + colors[103]=0xffaa55ff; + colors[104]=0xffaaaa00; + colors[105]=0xffaaaa55; + colors[106]=0xffaaaaaa; + colors[107]=0xffaaaaff; + colors[108]=0xffaaff00; + colors[109]=0xffaaff55; + colors[110]=0xffaaffaa; + colors[111]=0xffaaffff; + colors[112]=0xffff0000; + colors[113]=0xffff0055; + colors[114]=0xffff00aa; + colors[115]=0xffff00ff; + colors[116]=0xffff5500; + colors[117]=0xffff5555; + colors[118]=0xffff55aa; + colors[119]=0xffff55ff; + colors[120]=0xffffaa00; + colors[121]=0xffffaa55; + colors[122]=0xffffaaaa; + colors[123]=0xffffaaff; + colors[124]=0xffffff00; + colors[125]=0xffffff55; + colors[126]=0xffffffaa; + colors[127]=0xffffffff; + colors[128]=0xff000000; + colors[129]=0xff000055; + colors[130]=0xff0000aa; + colors[131]=0xff0000ff; + colors[132]=0xff005500; + colors[133]=0xff005555; + colors[134]=0xff0055aa; + colors[135]=0xff0055ff; + colors[136]=0xff00aa00; + colors[137]=0xff00aa55; + colors[138]=0xff00aaaa; + colors[139]=0xff00aaff; + colors[140]=0xff00ff00; + colors[141]=0xff00ff55; + colors[142]=0xff00ffaa; + colors[143]=0xff00ffff; + colors[144]=0xff550000; + colors[145]=0xff550055; + colors[146]=0xff5500aa; + colors[147]=0xff5500ff; + colors[148]=0xff555500; + colors[149]=0xff555555; + colors[150]=0xff5555aa; + colors[151]=0xff5555ff; + colors[152]=0xff55aa00; + colors[153]=0xff55aa55; + colors[154]=0xff55aaaa; + colors[155]=0xff55aaff; + colors[156]=0xff55ff00; + colors[157]=0xff55ff55; + colors[158]=0xff55ffaa; + colors[159]=0xff55ffff; + colors[160]=0xffaa0000; + colors[161]=0xffaa0055; + colors[162]=0xffaa00aa; + colors[163]=0xffaa00ff; + colors[164]=0xffaa5500; + colors[165]=0xffaa5555; + colors[166]=0xffaa55aa; + colors[167]=0xffaa55ff; + colors[168]=0xffaaaa00; + colors[169]=0xffaaaa55; + colors[170]=0xffaaaaaa; + colors[171]=0xffaaaaff; + colors[172]=0xffaaff00; + colors[173]=0xffaaff55; + colors[174]=0xffaaffaa; + colors[175]=0xffaaffff; + colors[176]=0xffff0000; + colors[177]=0xffff0055; + colors[178]=0xffff00aa; + colors[179]=0xffff00ff; + colors[180]=0xffff5500; + colors[181]=0xffff5555; + colors[182]=0xffff55aa; + colors[183]=0xffff55ff; + colors[184]=0xffffaa00; + colors[185]=0xffffaa55; + colors[186]=0xffffaaaa; + colors[187]=0xffffaaff; + colors[188]=0xffffff00; + colors[189]=0xffffff55; + colors[190]=0xffffffaa; + colors[191]=0xffffffff; + colors[192]=0xff000000; + colors[193]=0xff000055; + colors[194]=0xff0000aa; + colors[195]=0xff0000ff; + colors[196]=0xff005500; + colors[197]=0xff005555; + colors[198]=0xff0055aa; + colors[199]=0xff0055ff; + colors[200]=0xff00aa00; + colors[201]=0xff00aa55; + colors[202]=0xff00aaaa; + colors[203]=0xff00aaff; + colors[204]=0xff00ff00; + colors[205]=0xff00ff55; + colors[206]=0xff00ffaa; + colors[207]=0xff00ffff; + colors[208]=0xff550000; + colors[209]=0xff550055; + colors[210]=0xff5500aa; + colors[211]=0xff5500ff; + colors[212]=0xff555500; + colors[213]=0xff555555; + colors[214]=0xff5555aa; + colors[215]=0xff5555ff; + colors[216]=0xff55aa00; + colors[217]=0xff55aa55; + colors[218]=0xff55aaaa; + colors[219]=0xff55aaff; + colors[220]=0xff55ff00; + colors[221]=0xff55ff55; + colors[222]=0xff55ffaa; + colors[223]=0xff55ffff; + colors[224]=0xffaa0000; + colors[225]=0xffaa0055; + colors[226]=0xffaa00aa; + colors[227]=0xffaa00ff; + colors[228]=0xffaa5500; + colors[229]=0xffaa5555; + colors[230]=0xffaa55aa; + colors[231]=0xffaa55ff; + colors[232]=0xffaaaa00; + colors[233]=0xffaaaa55; + colors[234]=0xffaaaaaa; + colors[235]=0xffaaaaff; + colors[236]=0xffaaff00; + colors[237]=0xffaaff55; + colors[238]=0xffaaffaa; + colors[239]=0xffaaffff; + colors[240]=0xffff0000; + colors[241]=0xffff0055; + colors[242]=0xffff00aa; + colors[243]=0xffff00ff; + colors[244]=0xffff5500; + colors[245]=0xffff5555; + colors[246]=0xffff55aa; + colors[247]=0xffff55ff; + colors[248]=0xffffaa00; + colors[249]=0xffffaa55; + colors[250]=0xffffaaaa; + colors[251]=0xffffaaff; + colors[252]=0xffffff00; + colors[253]=0xffffff55; + colors[254]=0xffffffaa; + colors[255]=0xffffffff; + + } +} diff --git a/app/src/main/java/android/androidVNC/ColorModel8.java b/app/src/main/java/android/androidVNC/ColorModel8.java new file mode 100644 index 0000000..0c1b2de --- /dev/null +++ b/app/src/main/java/android/androidVNC/ColorModel8.java @@ -0,0 +1,266 @@ +package android.androidVNC; + +public class ColorModel8 { + + public final static int [] colors; + + static { + colors = new int[256]; + colors[0]=0xff000000; + colors[1]=0xff0000ff; + colors[2]=0xff00ff00; + colors[3]=0xff00ffff; + colors[4]=0xffff0000; + colors[5]=0xffff00ff; + colors[6]=0xffffff00; + colors[7]=0xffffffff; + colors[8]=0xff000000; + colors[9]=0xff0000ff; + colors[10]=0xff00ff00; + colors[11]=0xff00ffff; + colors[12]=0xffff0000; + colors[13]=0xffff00ff; + colors[14]=0xffffff00; + colors[15]=0xffffffff; + colors[16]=0xff000000; + colors[17]=0xff0000ff; + colors[18]=0xff00ff00; + colors[19]=0xff00ffff; + colors[20]=0xffff0000; + colors[21]=0xffff00ff; + colors[22]=0xffffff00; + colors[23]=0xffffffff; + colors[24]=0xff000000; + colors[25]=0xff0000ff; + colors[26]=0xff00ff00; + colors[27]=0xff00ffff; + colors[28]=0xffff0000; + colors[29]=0xffff00ff; + colors[30]=0xffffff00; + colors[31]=0xffffffff; + colors[32]=0xff000000; + colors[33]=0xff0000ff; + colors[34]=0xff00ff00; + colors[35]=0xff00ffff; + colors[36]=0xffff0000; + colors[37]=0xffff00ff; + colors[38]=0xffffff00; + colors[39]=0xffffffff; + colors[40]=0xff000000; + colors[41]=0xff0000ff; + colors[42]=0xff00ff00; + colors[43]=0xff00ffff; + colors[44]=0xffff0000; + colors[45]=0xffff00ff; + colors[46]=0xffffff00; + colors[47]=0xffffffff; + colors[48]=0xff000000; + colors[49]=0xff0000ff; + colors[50]=0xff00ff00; + colors[51]=0xff00ffff; + colors[52]=0xffff0000; + colors[53]=0xffff00ff; + colors[54]=0xffffff00; + colors[55]=0xffffffff; + colors[56]=0xff000000; + colors[57]=0xff0000ff; + colors[58]=0xff00ff00; + colors[59]=0xff00ffff; + colors[60]=0xffff0000; + colors[61]=0xffff00ff; + colors[62]=0xffffff00; + colors[63]=0xffffffff; + colors[64]=0xff000000; + colors[65]=0xff0000ff; + colors[66]=0xff00ff00; + colors[67]=0xff00ffff; + colors[68]=0xffff0000; + colors[69]=0xffff00ff; + colors[70]=0xffffff00; + colors[71]=0xffffffff; + colors[72]=0xff000000; + colors[73]=0xff0000ff; + colors[74]=0xff00ff00; + colors[75]=0xff00ffff; + colors[76]=0xffff0000; + colors[77]=0xffff00ff; + colors[78]=0xffffff00; + colors[79]=0xffffffff; + colors[80]=0xff000000; + colors[81]=0xff0000ff; + colors[82]=0xff00ff00; + colors[83]=0xff00ffff; + colors[84]=0xffff0000; + colors[85]=0xffff00ff; + colors[86]=0xffffff00; + colors[87]=0xffffffff; + colors[88]=0xff000000; + colors[89]=0xff0000ff; + colors[90]=0xff00ff00; + colors[91]=0xff00ffff; + colors[92]=0xffff0000; + colors[93]=0xffff00ff; + colors[94]=0xffffff00; + colors[95]=0xffffffff; + colors[96]=0xff000000; + colors[97]=0xff0000ff; + colors[98]=0xff00ff00; + colors[99]=0xff00ffff; + colors[100]=0xffff0000; + colors[101]=0xffff00ff; + colors[102]=0xffffff00; + colors[103]=0xffffffff; + colors[104]=0xff000000; + colors[105]=0xff0000ff; + colors[106]=0xff00ff00; + colors[107]=0xff00ffff; + colors[108]=0xffff0000; + colors[109]=0xffff00ff; + colors[110]=0xffffff00; + colors[111]=0xffffffff; + colors[112]=0xff000000; + colors[113]=0xff0000ff; + colors[114]=0xff00ff00; + colors[115]=0xff00ffff; + colors[116]=0xffff0000; + colors[117]=0xffff00ff; + colors[118]=0xffffff00; + colors[119]=0xffffffff; + colors[120]=0xff000000; + colors[121]=0xff0000ff; + colors[122]=0xff00ff00; + colors[123]=0xff00ffff; + colors[124]=0xffff0000; + colors[125]=0xffff00ff; + colors[126]=0xffffff00; + colors[127]=0xffffffff; + colors[128]=0xff000000; + colors[129]=0xff0000ff; + colors[130]=0xff00ff00; + colors[131]=0xff00ffff; + colors[132]=0xffff0000; + colors[133]=0xffff00ff; + colors[134]=0xffffff00; + colors[135]=0xffffffff; + colors[136]=0xff000000; + colors[137]=0xff0000ff; + colors[138]=0xff00ff00; + colors[139]=0xff00ffff; + colors[140]=0xffff0000; + colors[141]=0xffff00ff; + colors[142]=0xffffff00; + colors[143]=0xffffffff; + colors[144]=0xff000000; + colors[145]=0xff0000ff; + colors[146]=0xff00ff00; + colors[147]=0xff00ffff; + colors[148]=0xffff0000; + colors[149]=0xffff00ff; + colors[150]=0xffffff00; + colors[151]=0xffffffff; + colors[152]=0xff000000; + colors[153]=0xff0000ff; + colors[154]=0xff00ff00; + colors[155]=0xff00ffff; + colors[156]=0xffff0000; + colors[157]=0xffff00ff; + colors[158]=0xffffff00; + colors[159]=0xffffffff; + colors[160]=0xff000000; + colors[161]=0xff0000ff; + colors[162]=0xff00ff00; + colors[163]=0xff00ffff; + colors[164]=0xffff0000; + colors[165]=0xffff00ff; + colors[166]=0xffffff00; + colors[167]=0xffffffff; + colors[168]=0xff000000; + colors[169]=0xff0000ff; + colors[170]=0xff00ff00; + colors[171]=0xff00ffff; + colors[172]=0xffff0000; + colors[173]=0xffff00ff; + colors[174]=0xffffff00; + colors[175]=0xffffffff; + colors[176]=0xff000000; + colors[177]=0xff0000ff; + colors[178]=0xff00ff00; + colors[179]=0xff00ffff; + colors[180]=0xffff0000; + colors[181]=0xffff00ff; + colors[182]=0xffffff00; + colors[183]=0xffffffff; + colors[184]=0xff000000; + colors[185]=0xff0000ff; + colors[186]=0xff00ff00; + colors[187]=0xff00ffff; + colors[188]=0xffff0000; + colors[189]=0xffff00ff; + colors[190]=0xffffff00; + colors[191]=0xffffffff; + colors[192]=0xff000000; + colors[193]=0xff0000ff; + colors[194]=0xff00ff00; + colors[195]=0xff00ffff; + colors[196]=0xffff0000; + colors[197]=0xffff00ff; + colors[198]=0xffffff00; + colors[199]=0xffffffff; + colors[200]=0xff000000; + colors[201]=0xff0000ff; + colors[202]=0xff00ff00; + colors[203]=0xff00ffff; + colors[204]=0xffff0000; + colors[205]=0xffff00ff; + colors[206]=0xffffff00; + colors[207]=0xffffffff; + colors[208]=0xff000000; + colors[209]=0xff0000ff; + colors[210]=0xff00ff00; + colors[211]=0xff00ffff; + colors[212]=0xffff0000; + colors[213]=0xffff00ff; + colors[214]=0xffffff00; + colors[215]=0xffffffff; + colors[216]=0xff000000; + colors[217]=0xff0000ff; + colors[218]=0xff00ff00; + colors[219]=0xff00ffff; + colors[220]=0xffff0000; + colors[221]=0xffff00ff; + colors[222]=0xffffff00; + colors[223]=0xffffffff; + colors[224]=0xff000000; + colors[225]=0xff0000ff; + colors[226]=0xff00ff00; + colors[227]=0xff00ffff; + colors[228]=0xffff0000; + colors[229]=0xffff00ff; + colors[230]=0xffffff00; + colors[231]=0xffffffff; + colors[232]=0xff000000; + colors[233]=0xff0000ff; + colors[234]=0xff00ff00; + colors[235]=0xff00ffff; + colors[236]=0xffff0000; + colors[237]=0xffff00ff; + colors[238]=0xffffff00; + colors[239]=0xffffffff; + colors[240]=0xff000000; + colors[241]=0xff0000ff; + colors[242]=0xff00ff00; + colors[243]=0xff00ffff; + colors[244]=0xffff0000; + colors[245]=0xffff00ff; + colors[246]=0xffffff00; + colors[247]=0xffffffff; + colors[248]=0xff000000; + colors[249]=0xff0000ff; + colors[250]=0xff00ff00; + colors[251]=0xff00ffff; + colors[252]=0xffff0000; + colors[253]=0xffff00ff; + colors[254]=0xffffff00; + colors[255]=0xffffffff; + } +} diff --git a/app/src/main/java/android/androidVNC/CompactBitmapData.java b/app/src/main/java/android/androidVNC/CompactBitmapData.java new file mode 100644 index 0000000..e256516 --- /dev/null +++ b/app/src/main/java/android/androidVNC/CompactBitmapData.java @@ -0,0 +1,110 @@ +/** + * Copyright (C) 2009 Michael A. MacDonald + */ +package android.androidVNC; + +import java.io.IOException; + +import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.graphics.Rect; + +import com.vectras.qemu.Config; + +/** + * @author Michael A. MacDonald + * + */ +class CompactBitmapData extends AbstractBitmapData { + + class CompactBitmapDrawable extends AbstractBitmapDrawable + { + CompactBitmapDrawable() + { + super(CompactBitmapData.this); + } + /* (non-Javadoc) + * @see android.graphics.drawable.DrawableContainer#draw(android.graphics.Canvas) + */ + @Override + public void draw(Canvas canvas) { + draw(canvas, 0, 0); + } + } + + CompactBitmapData(RfbProto rfb, VncCanvas c) + { + super(rfb,c); + bitmapwidth=framebufferwidth; + bitmapheight=framebufferheight; + + mbitmap = Bitmap.createBitmap(rfb.framebufferWidth, rfb.framebufferHeight, Config.bitmapConfig); + memGraphics = new Canvas(mbitmap); + bitmapPixels = new int[rfb.framebufferWidth * rfb.framebufferHeight]; + } + + @Override + void writeFullUpdateRequest(boolean incremental) throws IOException { + rfb.writeFramebufferUpdateRequest(0, 0, framebufferwidth, framebufferheight, incremental); + } + + @Override + boolean validDraw(int x, int y, int w, int h) { + return true; + } + + @Override + int offset(int x, int y) { + return y * bitmapwidth + x; + } + + /* (non-Javadoc) + * @see android.androidVNC.AbstractBitmapData#createDrawable() + */ + @Override + AbstractBitmapDrawable createDrawable() { + return new CompactBitmapDrawable(); + } + + /* (non-Javadoc) + * @see android.androidVNC.AbstractBitmapData#updateBitmap(int, int, int, int) + */ + @Override + void updateBitmap(int x, int y, int w, int h) { + mbitmap.setPixels(bitmapPixels, offset(x,y), bitmapwidth, x, y, w, h); + } + + /* (non-Javadoc) + * @see android.androidVNC.AbstractBitmapData#copyRect(android.graphics.Rect, android.graphics.Rect, android.graphics.Paint) + */ + @Override + void copyRect(Rect src, Rect dest, Paint paint) { + memGraphics.drawBitmap(mbitmap, src, dest, paint); + } + + /* (non-Javadoc) + * @see android.androidVNC.AbstractBitmapData#drawRect(int, int, int, int, android.graphics.Paint) + */ + @Override + void drawRect(int x, int y, int w, int h, Paint paint) { + memGraphics.drawRect(x, y, x + w, y + h, paint); + } + + /* (non-Javadoc) + * @see android.androidVNC.AbstractBitmapData#scrollChanged(int, int) + */ + @Override + void scrollChanged(int newx, int newy) { + // Don't need to do anything here + } + + /* (non-Javadoc) + * @see android.androidVNC.AbstractBitmapData#syncScroll() + */ + @Override + void syncScroll() { + // Don't need anything here either + + } +} diff --git a/app/src/main/java/android/androidVNC/ConnectionBean.java b/app/src/main/java/android/androidVNC/ConnectionBean.java new file mode 100644 index 0000000..5a27c30 --- /dev/null +++ b/app/src/main/java/android/androidVNC/ConnectionBean.java @@ -0,0 +1,181 @@ +/** + * Copyright (C) 2009 Michael A. MacDonald + */ +package android.androidVNC; + +import android.widget.ImageView.ScaleType; + +import com.vectras.qemu.Config; + +/** + * @author Michael A. MacDonald + * + */ +public class ConnectionBean { + + private String address = "localhost"; + private String password = ""; + private int port = 5901; + private String colorModel = COLORMODEL.C64.nameString(); + private String InputMode = VncCanvasActivity.TOUCH_ZOOM_MODE; + private String scaleMode = ""; + private String nickname = "limbo"; + private long forceFull = 0; + private boolean useLocalCursor = false; + private boolean followMouse = true; + private String userName; + private long id = 0; + + public ConnectionBean() { + setAddress(Config.defaultVNCHost); + setUserName(Config.defaultVNCUsername); + setPassword(Config.defaultVNCPasswd); + setPort(Config.defaultVNCPort + 5900); + setColorModel(Config.defaultVNCColorMode); + if (Config.enable_qemu_fullScreen) + setScaleMode(Config.defaultFullscreenScaleMode); + else + setScaleMode(Config.defaultScaleModeCenter); + setInputMode(Config.defaultInputMode); + } + + private void setUserName(String string) { + + this.userName = string; + + } + + public void setInputMode(String touchZoomMode) { + + this.InputMode = touchZoomMode; + + } + + void setPort(int i) { + + this.port = i; + } + + void setColorModel(String nameString) { + + this.colorModel = nameString; + + } + + void setAddress(String string) { + + this.address = string; + } + + void setPassword(String string) { + + this.password = string; + } + + public long get_Id() { + + return 0; + } + + ScaleType getScaleMode() { + return ScaleType.valueOf(getScaleModeAsString()); + } + + private String getScaleModeAsString() { + + return scaleMode; + } + + void setScaleMode(ScaleType value) { + setScaleModeAsString(value.toString()); + } + + private void setScaleModeAsString(String string) { + + this.scaleMode = string; + + } + + public String getAddress() { + + return this.address; + } + + public void setNickname(String address2) { + + this.nickname = address2; + } + + public int getPort() { + + return port; + } + + public String getInputMode() { + + return this.InputMode; + } + + public String getPassword() { + + return this.password; + } + + public long getForceFull() { + + return this.forceFull; + } + + public boolean getUseLocalCursor() { + + return this.useLocalCursor; + } + + public String getNickname() { + + return nickname; + } + + public String getColorModel() { + + return this.colorModel; + } + + public void setForceFull(long l) { + + this.forceFull = l; + } + + public void setUseLocalCursor(boolean checked) { + + this.setUseLocalCursor(checked); + } + + public void setFollowMouse(boolean b) { + + this.followMouse = b; + + } + + public boolean getFollowMouse() { + + return this.followMouse; + } + + public String getUserName() { + + return userName; + } + + public void setConnectionId(long get_Id) { + + this.id = get_Id; + + } + + public boolean getFollowPan() { + + return false; + } + +} diff --git a/app/src/main/java/android/androidVNC/ConnectionSettable.java b/app/src/main/java/android/androidVNC/ConnectionSettable.java new file mode 100644 index 0000000..dfc64cc --- /dev/null +++ b/app/src/main/java/android/androidVNC/ConnectionSettable.java @@ -0,0 +1,12 @@ +/** + * + */ +package android.androidVNC; + +/** + * @author mike + * + */ +interface ConnectionSettable { + void setConnection(ConnectionBean connection); +} diff --git a/app/src/main/java/android/androidVNC/DH.java b/app/src/main/java/android/androidVNC/DH.java new file mode 100644 index 0000000..aaf6b10 --- /dev/null +++ b/app/src/main/java/android/androidVNC/DH.java @@ -0,0 +1,183 @@ +package android.androidVNC; +// CRYPTO LIBRARY FOR EXCHANGING KEYS +// USING THE DIFFIE-HELLMAN KEY EXCHANGE PROTOCOL + +// The diffie-hellman can be used to securely exchange keys +// between parties, where a third party eavesdropper given +// the values being transmitted cannot determine the key. + +// Implemented by Lee Griffiths, Jan 2004. +// This software is freeware, you may use it to your discretion, +// however by doing so you take full responsibility for any damage +// it may cause. + +// Hope you find it useful, even if you just use some of the functions +// out of it like the prime number generator and the XtoYmodN function. + +// It would be great if you could send me emails to: lee.griffiths@first4internet.co.uk +// with any suggestions, comments, or questions! + +// Enjoy. + +// Adopted to ms-logon for ultravnc and ported to Java by marscha, 2006. + +//import java.lang.Math; + +public class DH { + + public DH() { + maxNum = (((long) 1) << DH_MAX_BITS) - 1; + } + + public DH(long generator, long modulus) throws Exception { + maxNum = (((long) 1) << DH_MAX_BITS) - 1; + if (generator >= maxNum || modulus >= maxNum) + throw new Exception("Modulus or generator too large."); + gen = generator; + mod = modulus; + } + + private long rng(long limit) { + return (long) (java.lang.Math.random() * limit); + } + + //Performs the miller-rabin primality test on a guessed prime n. + //trials is the number of attempts to verify this, because the function + //is not 100% accurate it may be a composite. However setting the trial + //value to around 5 should guarantee success even with very large primes + private boolean millerRabin (long n, int trials) { + long a = 0; + + for (int i = 0; i < trials; i++) { + a = rng(n - 3) + 2;// gets random value in [2..n-1] + if (XpowYmodN(a, n - 1, n) != 1) return false; //n composite, return false + } + return true; // n probably prime + } + + //Generates a large prime number by + //choosing a randomly large integer, and ensuring the value is odd + //then uses the miller-rabin primality test on it to see if it is prime + //if not the value gets increased until it is prime + private long generatePrime() { + long prime = 0; + + do { + long start = rng(maxNum); + prime = tryToGeneratePrime(start); + } while (prime == 0); + return prime; + } + + private long tryToGeneratePrime(long prime) { + //ensure it is an odd number + if ((prime & 1) == 0) + prime += 1; + + long cnt = 0; + while (!millerRabin(prime, 25) && (cnt++ < DH_RANGE) && prime < maxNum) { + prime += 2; + if ((prime % 3) == 0) prime += 2; + } + return (cnt >= DH_RANGE || prime >= maxNum) ? 0 : prime; + } + + //Raises X to the power Y in modulus N + //the values of X, Y, and N can be massive, and this can be + //achieved by first calculating X to the power of 2 then + //using power chaining over modulus N + private long XpowYmodN(long x, long y, long N) { + long result = 1; + final long oneShift63 = ((long) 1) << 63; + + for (int i = 0; i < 64; y <<= 1, i++){ + result = result * result % N; + if ((y & oneShift63) != 0) + result = result * x % N; + } + return result; + } + + public void createKeys() { + gen = generatePrime(); + mod = generatePrime(); + + if (gen > mod) { + long swap = gen; + gen = mod; + mod = swap; + } + } + + public long createInterKey() { + priv = rng(maxNum); + return pub = XpowYmodN(gen,priv,mod); + } + + public long createEncryptionKey(long interKey) throws Exception { + if (interKey >= maxNum){ + throw new Exception("interKey too large"); + } + return key = XpowYmodN(interKey,priv,mod); + } + + + public long getValue(int flags) { + switch (flags) { + case DH_MOD: + return mod; + case DH_GEN: + return gen; + case DH_PRIV: + return priv; + case DH_PUB: + return pub; + case DH_KEY: + return key; + default: + return (long) 0; + } + } + + public int bits(long number){ + for (int i = 0; i < 64; i++){ + number /= 2; + if (number < 2) return i; + } + return 0; + } + + public static byte[] longToBytes(long number) { + byte[] bytes = new byte[8]; + for (int i = 0; i < 8; i++) { + bytes[i] = (byte) (0xff & (number >> (8 * (7 - i)))); + } + return bytes; + } + + public static long bytesToLong(byte[] bytes) { + long result = 0; + for (int i = 0; i < 8; i++) { + result <<= 8; + result += (byte) bytes[i]; + } + return result; + } + + private long gen; + private long mod; + private long priv; + private long pub; + private long key; + private long maxNum; + + private static final int DH_MAX_BITS = 31; + private static final int DH_RANGE = 100; + + private static final int DH_MOD = 1; + private static final int DH_GEN = 2; + private static final int DH_PRIV = 3; + private static final int DH_PUB = 4; + private static final int DH_KEY = 5; + +} \ No newline at end of file diff --git a/app/src/main/java/android/androidVNC/DPadMouseKeyHandler.java b/app/src/main/java/android/androidVNC/DPadMouseKeyHandler.java new file mode 100644 index 0000000..5f75df5 --- /dev/null +++ b/app/src/main/java/android/androidVNC/DPadMouseKeyHandler.java @@ -0,0 +1,117 @@ +/** + * Copyright (c) 2010 Michael A. MacDonald + */ +package android.androidVNC; + +import android.graphics.PointF; +import android.os.Handler; +import android.view.KeyEvent; +import android.view.MotionEvent; + +/** + * Input handlers delegate to this class to handle keystrokes; this detects keystrokes + * from the DPad and uses them to perform mouse actions; other keystrokes are passed to + * VncCanvasActivity.defaultKeyXXXHandler + * + * @author Michael A. MacDonald + * + */ +class DPadMouseKeyHandler { + private MouseMover mouseMover; + private boolean mouseDown; + private VncCanvasActivity activity; + private VncCanvas canvas; + private boolean isMoving; + + DPadMouseKeyHandler(VncCanvasActivity activity, Handler handler) + { + this.activity = activity; + canvas = activity.vncCanvas; + mouseMover = new MouseMover(activity, handler); + } + + public boolean onKeyDown(int keyCode, KeyEvent evt) { + int xv = 0; + int yv = 0; + boolean result = true; + switch (keyCode) { +// case KeyEvent.KEYCODE_DPAD_LEFT: +// xv = -1; +// break; +// case KeyEvent.KEYCODE_DPAD_RIGHT: +// xv = 1; +// break; +// case KeyEvent.KEYCODE_DPAD_UP: +// yv = -1; +// break; +// case KeyEvent.KEYCODE_DPAD_DOWN: +// yv = 1; +// break; +// case KeyEvent.KEYCODE_DPAD_CENTER: +// if (!mouseDown) { +// mouseDown = true; +// result = canvas.processPointerEvent(canvas.mouseX, canvas.mouseY, MotionEvent.ACTION_DOWN, evt.getMetaState(), mouseDown, canvas.cameraButtonDown); +// } +// break; + default: + result = activity.defaultKeyDownHandler(keyCode, evt); + break; + } + if ((xv != 0 || yv != 0) && !isMoving) { + final int x = xv; + final int y = yv; + isMoving = true; + mouseMover.start(x, y, new Panner.VelocityUpdater() { + + /* + * (non-Javadoc) + * + * @see android.androidVNC.Panner.VelocityUpdater#updateVelocity(android.graphics.Point, + * long) + */ + @Override + public boolean updateVelocity(PointF p, long interval) { + double scale = (1.2 * (double) interval / 50.0); + if (Math.abs(p.x) < 500) + p.x += (int) (scale * x); + if (Math.abs(p.y) < 500) + p.y += (int) (scale * y); + return true; + } + + }); + canvas.processPointerEvent(canvas.mouseX + x, canvas.mouseY + y, MotionEvent.ACTION_MOVE, evt.getMetaState(), + mouseDown, canvas.cameraButtonDown, false, false); + + } + return result; + } + + public boolean onKeyUp(int keyCode, KeyEvent evt) { + boolean result = false; + + switch (keyCode) { +// case KeyEvent.KEYCODE_DPAD_LEFT: +// case KeyEvent.KEYCODE_DPAD_RIGHT: +// case KeyEvent.KEYCODE_DPAD_UP: +// case KeyEvent.KEYCODE_DPAD_DOWN: +// mouseMover.stop(); +// isMoving = false; +// result = true; +// break; + case KeyEvent.KEYCODE_DPAD_CENTER: + if (mouseDown) { + mouseDown = false; + result = canvas.processPointerEvent(canvas.mouseX, canvas.mouseY, MotionEvent.ACTION_UP, evt.getMetaState(), + mouseDown, canvas.cameraButtonDown, false, false); + } else { + result = true; + } + break; + default: + result = activity.defaultKeyUpHandler(keyCode, evt); + break; + } + return result; + } +} diff --git a/app/src/main/java/android/androidVNC/DesCipher.java b/app/src/main/java/android/androidVNC/DesCipher.java new file mode 100644 index 0000000..2d7bed3 --- /dev/null +++ b/app/src/main/java/android/androidVNC/DesCipher.java @@ -0,0 +1,539 @@ +// +// This DES class has been extracted from package Acme.Crypto for use in VNC. +// The bytebit[] array has been reversed so that the most significant bit +// in each byte of the key is ignored, not the least significant. Also the +// unnecessary odd parity code has been removed. +// +// These changes are: +// Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. +// +// This software is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// + +// DesCipher - the DES encryption method +// +// The meat of this code is by Dave Zimmerman , and is: +// +// Copyright (c) 1996 Widget Workshop, Inc. All Rights Reserved. +// +// Permission to use, copy, modify, and distribute this software +// and its documentation for NON-COMMERCIAL or COMMERCIAL purposes and +// without fee is hereby granted, provided that this copyright notice is kept +// intact. +// +// WIDGET WORKSHOP MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY +// OF THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +// TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +// PARTICULAR PURPOSE, OR NON-INFRINGEMENT. WIDGET WORKSHOP SHALL NOT BE LIABLE +// FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR +// DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. +// +// THIS SOFTWARE IS NOT DESIGNED OR INTENDED FOR USE OR RESALE AS ON-LINE +// CONTROL EQUIPMENT IN HAZARDOUS ENVIRONMENTS REQUIRING FAIL-SAFE +// PERFORMANCE, SUCH AS IN THE OPERATION OF NUCLEAR FACILITIES, AIRCRAFT +// NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL, DIRECT LIFE +// SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH THE FAILURE OF THE +// SOFTWARE COULD LEAD DIRECTLY TO DEATH, PERSONAL INJURY, OR SEVERE +// PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH RISK ACTIVITIES"). WIDGET WORKSHOP +// SPECIFICALLY DISCLAIMS ANY EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR +// HIGH RISK ACTIVITIES. +// +// +// The rest is: +// +// Copyright (C) 1996 by Jef Poskanzer . All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +// SUCH DAMAGE. +// +// Visit the ACME Labs Java page for up-to-date versions of this and other +// fine Java utilities: http://www.acme.com/java/ + +/// The DES encryption method. +//

+// This is surprisingly fast, for pure Java. On a SPARC 20, wrapped +// in Acme.Crypto.EncryptedOutputStream or Acme.Crypto.EncryptedInputStream, +// it does around 7000 bytes/second. +//

+// Most of this code is by Dave Zimmerman , and is +// Copyright (c) 1996 Widget Workshop, Inc. See the source file for details. +//

+// Fetch the software.
+// Fetch the entire Acme package. +//

+// @see Des3Cipher +// @see EncryptedOutputStream +// @see EncryptedInputStream + +package android.androidVNC; + +//- import java.io.*; + + +public class DesCipher + { + + // Constructor, byte-array key. + public DesCipher( byte[] key ) + { + setKey( key ); + } + + // Key routines. + + private int[] encryptKeys = new int[32]; + private int[] decryptKeys = new int[32]; + + /// Set the key. + public void setKey( byte[] key ) + { + deskey( key, true, encryptKeys ); + deskey( key, false, decryptKeys ); + } + + // Turn an 8-byte key into internal keys. + private void deskey( byte[] keyBlock, boolean encrypting, int[] KnL ) + { + int i, j, l, m, n; + int[] pc1m = new int[56]; + int[] pcr = new int[56]; + int[] kn = new int[32]; + + for ( j = 0; j < 56; ++j ) + { + l = pc1[j]; + m = l & 07; + pc1m[j] = ( (keyBlock[l >>> 3] & bytebit[m]) != 0 )? 1: 0; + } + + for ( i = 0; i < 16; ++i ) + { + if ( encrypting ) + m = i << 1; + else + m = (15-i) << 1; + n = m+1; + kn[m] = kn[n] = 0; + for ( j = 0; j < 28; ++j ) + { + l = j+totrot[i]; + if ( l < 28 ) + pcr[j] = pc1m[l]; + else + pcr[j] = pc1m[l-28]; + } + for ( j=28; j < 56; ++j ) + { + l = j+totrot[i]; + if ( l < 56 ) + pcr[j] = pc1m[l]; + else + pcr[j] = pc1m[l-28]; + } + for ( j = 0; j < 24; ++j ) + { + if ( pcr[pc2[j]] != 0 ) + kn[m] |= bigbyte[j]; + if ( pcr[pc2[j+24]] != 0 ) + kn[n] |= bigbyte[j]; + } + } + cookey( kn, KnL ); + } + + private void cookey( int[] raw, int KnL[] ) + { + int raw0, raw1; + int rawi, KnLi; + int i; + + for ( i = 0, rawi = 0, KnLi = 0; i < 16; ++i ) + { + raw0 = raw[rawi++]; + raw1 = raw[rawi++]; + KnL[KnLi] = (raw0 & 0x00fc0000) << 6; + KnL[KnLi] |= (raw0 & 0x00000fc0) << 10; + KnL[KnLi] |= (raw1 & 0x00fc0000) >>> 10; + KnL[KnLi] |= (raw1 & 0x00000fc0) >>> 6; + ++KnLi; + KnL[KnLi] = (raw0 & 0x0003f000) << 12; + KnL[KnLi] |= (raw0 & 0x0000003f) << 16; + KnL[KnLi] |= (raw1 & 0x0003f000) >>> 4; + KnL[KnLi] |= (raw1 & 0x0000003f); + ++KnLi; + } + } + + + // Block encryption routines. + + private int[] tempInts = new int[2]; + + /// Encrypt a block of eight bytes. + public void encrypt( byte[] clearText, int clearOff, byte[] cipherText, int cipherOff ) + { + squashBytesToInts( clearText, clearOff, tempInts, 0, 2 ); + des( tempInts, tempInts, encryptKeys ); + spreadIntsToBytes( tempInts, 0, cipherText, cipherOff, 2 ); + } + + /// Decrypt a block of eight bytes. + public void decrypt( byte[] cipherText, int cipherOff, byte[] clearText, int clearOff ) + { + squashBytesToInts( cipherText, cipherOff, tempInts, 0, 2 ); + des( tempInts, tempInts, decryptKeys ); + spreadIntsToBytes( tempInts, 0, clearText, clearOff, 2 ); + } + + // Encrypt a text which is a multiple of 8 bytes. + public void encryptText(byte[] clearText, byte[] cipherText, byte[] key) + { + int i, j; + + for(i=0; i<8; i++) + { + clearText[i] ^= key[i]; + } + encrypt(clearText, 0, cipherText, 0); + for(i=8; i0; i-=8) + { + decrypt(cipherText, i, clearText, i); + for(j=0; j<8; j++) + { + clearText[i+j] ^= cipherText[i+j-8]; + } + } + /* i = 0 */ + decrypt(cipherText, 0, clearText, 0); + for(i=0; i<8; i++) + { + clearText[i] ^= key[i]; + } + } + + // The DES function. + private void des( int[] inInts, int[] outInts, int[] keys ) + { + int fval, work, right, leftt; + int round; + int keysi = 0; + + leftt = inInts[0]; + right = inInts[1]; + + work = ((leftt >>> 4) ^ right) & 0x0f0f0f0f; + right ^= work; + leftt ^= (work << 4); + + work = ((leftt >>> 16) ^ right) & 0x0000ffff; + right ^= work; + leftt ^= (work << 16); + + work = ((right >>> 2) ^ leftt) & 0x33333333; + leftt ^= work; + right ^= (work << 2); + + work = ((right >>> 8) ^ leftt) & 0x00ff00ff; + leftt ^= work; + right ^= (work << 8); + right = (right << 1) | ((right >>> 31) & 1); + + work = (leftt ^ right) & 0xaaaaaaaa; + leftt ^= work; + right ^= work; + leftt = (leftt << 1) | ((leftt >>> 31) & 1); + + for ( round = 0; round < 8; ++round ) + { + work = (right << 28) | (right >>> 4); + work ^= keys[keysi++]; + fval = SP7[ work & 0x0000003f ]; + fval |= SP5[(work >>> 8) & 0x0000003f ]; + fval |= SP3[(work >>> 16) & 0x0000003f ]; + fval |= SP1[(work >>> 24) & 0x0000003f ]; + work = right ^ keys[keysi++]; + fval |= SP8[ work & 0x0000003f ]; + fval |= SP6[(work >>> 8) & 0x0000003f ]; + fval |= SP4[(work >>> 16) & 0x0000003f ]; + fval |= SP2[(work >>> 24) & 0x0000003f ]; + leftt ^= fval; + work = (leftt << 28) | (leftt >>> 4); + work ^= keys[keysi++]; + fval = SP7[ work & 0x0000003f ]; + fval |= SP5[(work >>> 8) & 0x0000003f ]; + fval |= SP3[(work >>> 16) & 0x0000003f ]; + fval |= SP1[(work >>> 24) & 0x0000003f ]; + work = leftt ^ keys[keysi++]; + fval |= SP8[ work & 0x0000003f ]; + fval |= SP6[(work >>> 8) & 0x0000003f ]; + fval |= SP4[(work >>> 16) & 0x0000003f ]; + fval |= SP2[(work >>> 24) & 0x0000003f ]; + right ^= fval; + } + + right = (right << 31) | (right >>> 1); + work = (leftt ^ right) & 0xaaaaaaaa; + leftt ^= work; + right ^= work; + leftt = (leftt << 31) | (leftt >>> 1); + work = ((leftt >>> 8) ^ right) & 0x00ff00ff; + right ^= work; + leftt ^= (work << 8); + work = ((leftt >>> 2) ^ right) & 0x33333333; + right ^= work; + leftt ^= (work << 2); + work = ((right >>> 16) ^ leftt) & 0x0000ffff; + leftt ^= work; + right ^= (work << 16); + work = ((right >>> 4) ^ leftt) & 0x0f0f0f0f; + leftt ^= work; + right ^= (work << 4); + outInts[0] = right; + outInts[1] = leftt; + } + + + // Tables, permutations, S-boxes, etc. + + private static byte[] bytebit = { + (byte)0x01, (byte)0x02, (byte)0x04, (byte)0x08, + (byte)0x10, (byte)0x20, (byte)0x40, (byte)0x80 + }; + private static int[] bigbyte = { + 0x800000, 0x400000, 0x200000, 0x100000, + 0x080000, 0x040000, 0x020000, 0x010000, + 0x008000, 0x004000, 0x002000, 0x001000, + 0x000800, 0x000400, 0x000200, 0x000100, + 0x000080, 0x000040, 0x000020, 0x000010, + 0x000008, 0x000004, 0x000002, 0x000001 + }; + private static byte[] pc1 = { + (byte)56, (byte)48, (byte)40, (byte)32, (byte)24, (byte)16, (byte) 8, + (byte) 0, (byte)57, (byte)49, (byte)41, (byte)33, (byte)25, (byte)17, + (byte) 9, (byte) 1, (byte)58, (byte)50, (byte)42, (byte)34, (byte)26, + (byte)18, (byte)10, (byte) 2, (byte)59, (byte)51, (byte)43, (byte)35, + (byte)62, (byte)54, (byte)46, (byte)38, (byte)30, (byte)22, (byte)14, + (byte) 6, (byte)61, (byte)53, (byte)45, (byte)37, (byte)29, (byte)21, + (byte)13, (byte) 5, (byte)60, (byte)52, (byte)44, (byte)36, (byte)28, + (byte)20, (byte)12, (byte) 4, (byte)27, (byte)19, (byte)11, (byte)3 + }; + private static int[] totrot = { + 1, 2, 4, 6, 8, 10, 12, 14, 15, 17, 19, 21, 23, 25, 27, 28 + }; + + private static byte[] pc2 = { + (byte)13, (byte)16, (byte)10, (byte)23, (byte) 0, (byte) 4, + (byte) 2, (byte)27, (byte)14, (byte) 5, (byte)20, (byte) 9, + (byte)22, (byte)18, (byte)11, (byte)3 , (byte)25, (byte) 7, + (byte)15, (byte) 6, (byte)26, (byte)19, (byte)12, (byte) 1, + (byte)40, (byte)51, (byte)30, (byte)36, (byte)46, (byte)54, + (byte)29, (byte)39, (byte)50, (byte)44, (byte)32, (byte)47, + (byte)43, (byte)48, (byte)38, (byte)55, (byte)33, (byte)52, + (byte)45, (byte)41, (byte)49, (byte)35, (byte)28, (byte)31, + }; + + private static int[] SP1 = { + 0x01010400, 0x00000000, 0x00010000, 0x01010404, + 0x01010004, 0x00010404, 0x00000004, 0x00010000, + 0x00000400, 0x01010400, 0x01010404, 0x00000400, + 0x01000404, 0x01010004, 0x01000000, 0x00000004, + 0x00000404, 0x01000400, 0x01000400, 0x00010400, + 0x00010400, 0x01010000, 0x01010000, 0x01000404, + 0x00010004, 0x01000004, 0x01000004, 0x00010004, + 0x00000000, 0x00000404, 0x00010404, 0x01000000, + 0x00010000, 0x01010404, 0x00000004, 0x01010000, + 0x01010400, 0x01000000, 0x01000000, 0x00000400, + 0x01010004, 0x00010000, 0x00010400, 0x01000004, + 0x00000400, 0x00000004, 0x01000404, 0x00010404, + 0x01010404, 0x00010004, 0x01010000, 0x01000404, + 0x01000004, 0x00000404, 0x00010404, 0x01010400, + 0x00000404, 0x01000400, 0x01000400, 0x00000000, + 0x00010004, 0x00010400, 0x00000000, 0x01010004 + }; + private static int[] SP2 = { + 0x80108020, 0x80008000, 0x00008000, 0x00108020, + 0x00100000, 0x00000020, 0x80100020, 0x80008020, + 0x80000020, 0x80108020, 0x80108000, 0x80000000, + 0x80008000, 0x00100000, 0x00000020, 0x80100020, + 0x00108000, 0x00100020, 0x80008020, 0x00000000, + 0x80000000, 0x00008000, 0x00108020, 0x80100000, + 0x00100020, 0x80000020, 0x00000000, 0x00108000, + 0x00008020, 0x80108000, 0x80100000, 0x00008020, + 0x00000000, 0x00108020, 0x80100020, 0x00100000, + 0x80008020, 0x80100000, 0x80108000, 0x00008000, + 0x80100000, 0x80008000, 0x00000020, 0x80108020, + 0x00108020, 0x00000020, 0x00008000, 0x80000000, + 0x00008020, 0x80108000, 0x00100000, 0x80000020, + 0x00100020, 0x80008020, 0x80000020, 0x00100020, + 0x00108000, 0x00000000, 0x80008000, 0x00008020, + 0x80000000, 0x80100020, 0x80108020, 0x00108000 + }; + private static int[] SP3 = { + 0x00000208, 0x08020200, 0x00000000, 0x08020008, + 0x08000200, 0x00000000, 0x00020208, 0x08000200, + 0x00020008, 0x08000008, 0x08000008, 0x00020000, + 0x08020208, 0x00020008, 0x08020000, 0x00000208, + 0x08000000, 0x00000008, 0x08020200, 0x00000200, + 0x00020200, 0x08020000, 0x08020008, 0x00020208, + 0x08000208, 0x00020200, 0x00020000, 0x08000208, + 0x00000008, 0x08020208, 0x00000200, 0x08000000, + 0x08020200, 0x08000000, 0x00020008, 0x00000208, + 0x00020000, 0x08020200, 0x08000200, 0x00000000, + 0x00000200, 0x00020008, 0x08020208, 0x08000200, + 0x08000008, 0x00000200, 0x00000000, 0x08020008, + 0x08000208, 0x00020000, 0x08000000, 0x08020208, + 0x00000008, 0x00020208, 0x00020200, 0x08000008, + 0x08020000, 0x08000208, 0x00000208, 0x08020000, + 0x00020208, 0x00000008, 0x08020008, 0x00020200 + }; + private static int[] SP4 = { + 0x00802001, 0x00002081, 0x00002081, 0x00000080, + 0x00802080, 0x00800081, 0x00800001, 0x00002001, + 0x00000000, 0x00802000, 0x00802000, 0x00802081, + 0x00000081, 0x00000000, 0x00800080, 0x00800001, + 0x00000001, 0x00002000, 0x00800000, 0x00802001, + 0x00000080, 0x00800000, 0x00002001, 0x00002080, + 0x00800081, 0x00000001, 0x00002080, 0x00800080, + 0x00002000, 0x00802080, 0x00802081, 0x00000081, + 0x00800080, 0x00800001, 0x00802000, 0x00802081, + 0x00000081, 0x00000000, 0x00000000, 0x00802000, + 0x00002080, 0x00800080, 0x00800081, 0x00000001, + 0x00802001, 0x00002081, 0x00002081, 0x00000080, + 0x00802081, 0x00000081, 0x00000001, 0x00002000, + 0x00800001, 0x00002001, 0x00802080, 0x00800081, + 0x00002001, 0x00002080, 0x00800000, 0x00802001, + 0x00000080, 0x00800000, 0x00002000, 0x00802080 + }; + private static int[] SP5 = { + 0x00000100, 0x02080100, 0x02080000, 0x42000100, + 0x00080000, 0x00000100, 0x40000000, 0x02080000, + 0x40080100, 0x00080000, 0x02000100, 0x40080100, + 0x42000100, 0x42080000, 0x00080100, 0x40000000, + 0x02000000, 0x40080000, 0x40080000, 0x00000000, + 0x40000100, 0x42080100, 0x42080100, 0x02000100, + 0x42080000, 0x40000100, 0x00000000, 0x42000000, + 0x02080100, 0x02000000, 0x42000000, 0x00080100, + 0x00080000, 0x42000100, 0x00000100, 0x02000000, + 0x40000000, 0x02080000, 0x42000100, 0x40080100, + 0x02000100, 0x40000000, 0x42080000, 0x02080100, + 0x40080100, 0x00000100, 0x02000000, 0x42080000, + 0x42080100, 0x00080100, 0x42000000, 0x42080100, + 0x02080000, 0x00000000, 0x40080000, 0x42000000, + 0x00080100, 0x02000100, 0x40000100, 0x00080000, + 0x00000000, 0x40080000, 0x02080100, 0x40000100 + }; + private static int[] SP6 = { + 0x20000010, 0x20400000, 0x00004000, 0x20404010, + 0x20400000, 0x00000010, 0x20404010, 0x00400000, + 0x20004000, 0x00404010, 0x00400000, 0x20000010, + 0x00400010, 0x20004000, 0x20000000, 0x00004010, + 0x00000000, 0x00400010, 0x20004010, 0x00004000, + 0x00404000, 0x20004010, 0x00000010, 0x20400010, + 0x20400010, 0x00000000, 0x00404010, 0x20404000, + 0x00004010, 0x00404000, 0x20404000, 0x20000000, + 0x20004000, 0x00000010, 0x20400010, 0x00404000, + 0x20404010, 0x00400000, 0x00004010, 0x20000010, + 0x00400000, 0x20004000, 0x20000000, 0x00004010, + 0x20000010, 0x20404010, 0x00404000, 0x20400000, + 0x00404010, 0x20404000, 0x00000000, 0x20400010, + 0x00000010, 0x00004000, 0x20400000, 0x00404010, + 0x00004000, 0x00400010, 0x20004010, 0x00000000, + 0x20404000, 0x20000000, 0x00400010, 0x20004010 + }; + private static int[] SP7 = { + 0x00200000, 0x04200002, 0x04000802, 0x00000000, + 0x00000800, 0x04000802, 0x00200802, 0x04200800, + 0x04200802, 0x00200000, 0x00000000, 0x04000002, + 0x00000002, 0x04000000, 0x04200002, 0x00000802, + 0x04000800, 0x00200802, 0x00200002, 0x04000800, + 0x04000002, 0x04200000, 0x04200800, 0x00200002, + 0x04200000, 0x00000800, 0x00000802, 0x04200802, + 0x00200800, 0x00000002, 0x04000000, 0x00200800, + 0x04000000, 0x00200800, 0x00200000, 0x04000802, + 0x04000802, 0x04200002, 0x04200002, 0x00000002, + 0x00200002, 0x04000000, 0x04000800, 0x00200000, + 0x04200800, 0x00000802, 0x00200802, 0x04200800, + 0x00000802, 0x04000002, 0x04200802, 0x04200000, + 0x00200800, 0x00000000, 0x00000002, 0x04200802, + 0x00000000, 0x00200802, 0x04200000, 0x00000800, + 0x04000002, 0x04000800, 0x00000800, 0x00200002 + }; + private static int[] SP8 = { + 0x10001040, 0x00001000, 0x00040000, 0x10041040, + 0x10000000, 0x10001040, 0x00000040, 0x10000000, + 0x00040040, 0x10040000, 0x10041040, 0x00041000, + 0x10041000, 0x00041040, 0x00001000, 0x00000040, + 0x10040000, 0x10000040, 0x10001000, 0x00001040, + 0x00041000, 0x00040040, 0x10040040, 0x10041000, + 0x00001040, 0x00000000, 0x00000000, 0x10040040, + 0x10000040, 0x10001000, 0x00041040, 0x00040000, + 0x00041040, 0x00040000, 0x10041000, 0x00001000, + 0x00000040, 0x10040040, 0x00001000, 0x00041040, + 0x10001000, 0x00000040, 0x10000040, 0x10040000, + 0x10040040, 0x10000000, 0x00040000, 0x10001040, + 0x00000000, 0x10041040, 0x00040040, 0x10000040, + 0x10040000, 0x10001000, 0x10001040, 0x00000000, + 0x10041040, 0x00041000, 0x00041000, 0x00001040, + 0x00001040, 0x00040040, 0x10000000, 0x10041000 + }; + + // Routines taken from other parts of the Acme utilities. + + /// Squash bytes down to ints. + public static void squashBytesToInts( byte[] inBytes, int inOff, int[] outInts, int outOff, int intLen ) + { + for ( int i = 0; i < intLen; ++i ) + outInts[outOff + i] = + ( ( inBytes[inOff + i * 4 ] & 0xff ) << 24 ) | + ( ( inBytes[inOff + i * 4 + 1] & 0xff ) << 16 ) | + ( ( inBytes[inOff + i * 4 + 2] & 0xff ) << 8 ) | + ( inBytes[inOff + i * 4 + 3] & 0xff ); + } + + /// Spread ints into bytes. + public static void spreadIntsToBytes( int[] inInts, int inOff, byte[] outBytes, int outOff, int intLen ) + { + for ( int i = 0; i < intLen; ++i ) + { + outBytes[outOff + i * 4 ] = (byte) ( inInts[inOff + i] >>> 24 ); + outBytes[outOff + i * 4 + 1] = (byte) ( inInts[inOff + i] >>> 16 ); + outBytes[outOff + i * 4 + 2] = (byte) ( inInts[inOff + i] >>> 8 ); + outBytes[outOff + i * 4 + 3] = (byte) inInts[inOff + i]; + } + } + } diff --git a/app/src/main/java/android/androidVNC/FitToScreenScaling.java b/app/src/main/java/android/androidVNC/FitToScreenScaling.java new file mode 100644 index 0000000..2fb7a20 --- /dev/null +++ b/app/src/main/java/android/androidVNC/FitToScreenScaling.java @@ -0,0 +1,57 @@ +/** + * Copyright (C) 2009 Michael A. MacDonald + */ +package android.androidVNC; + +import android.widget.ImageView.ScaleType; + +import com.vectras.vm.R; + +/** + * @author Michael A. MacDonald + */ +class FitToScreenScaling extends AbstractScaling { + + /** + * @param id + * @param scaleType + */ + FitToScreenScaling() { + super(R.id.itemFitToScreen, ScaleType.FIT_CENTER); + } + + /* (non-Javadoc) + * @see android.androidVNC.AbstractScaling#isAbleToPan() + */ + @Override + boolean isAbleToPan() { + return false; + } + + /* (non-Javadoc) + * @see android.androidVNC.AbstractScaling#isValidInputMode(int) + */ + @Override + boolean isValidInputMode(int mode) { + return mode == R.id.itemInputFitToScreen; + } + + /* (non-Javadoc) + * @see android.androidVNC.AbstractScaling#getDefaultHandlerId() + */ + @Override + int getDefaultHandlerId() { + return R.id.itemInputFitToScreen; + } + + /* (non-Javadoc) + * @see android.androidVNC.AbstractScaling#setCanvasScaleType(android.androidVNC.VncCanvas) + */ + @Override + public void setScaleTypeForActivity(VncCanvasActivity activity) { + super.setScaleTypeForActivity(activity); + activity.vncCanvas.absoluteXPosition = activity.vncCanvas.absoluteYPosition = 0; + activity.vncCanvas.scrollTo(0, 0); + } + +} diff --git a/app/src/main/java/android/androidVNC/FullBufferBitmapData.java b/app/src/main/java/android/androidVNC/FullBufferBitmapData.java new file mode 100644 index 0000000..668b40c --- /dev/null +++ b/app/src/main/java/android/androidVNC/FullBufferBitmapData.java @@ -0,0 +1,221 @@ +/** + * Copyright (c) 2010 Michael A. MacDonald + */ +package android.androidVNC; + +import java.io.IOException; +import java.util.Arrays; + +import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.graphics.Rect; +import android.widget.ImageView; + +import com.vectras.qemu.Config; + +/** + * @author Michael A. MacDonald + * + */ +class FullBufferBitmapData extends AbstractBitmapData { + + int xoffset; + int yoffset; + + /** + * @author Michael A. MacDonald + * + */ + class Drawable extends AbstractBitmapDrawable { + + /** + * @param data + */ + public Drawable(AbstractBitmapData data) { + super(data); + // TODO Auto-generated constructor stub + } + + /* (non-Javadoc) + * @see android.graphics.drawable.DrawableContainer#draw(android.graphics.Canvas) + */ + @Override + public void draw(Canvas canvas) { + if (vncCanvas.getScaleType() == ImageView.ScaleType.FIT_CENTER) + { + //canvas.drawBitmap(data.bitmapPixels, 0, data.framebufferwidth, xoffset, yoffset, framebufferwidth, framebufferheight, false, null); + + //XXX; Limbo: for Hardware accelerated surfaces we have to stop using the above deprecated method and use a bitmap-backed method + // this fixes the issue with Nougat Devices displaying black screen for 24bit color mode C24bit + Bitmap bitmapTmp = Bitmap.createBitmap(framebufferwidth, framebufferheight, Config.bitmapConfig); + bitmapTmp.setPixels(bitmapPixels, 0, data.framebufferwidth, 0, 0, framebufferwidth, framebufferheight); + canvas.drawBitmap(bitmapTmp, xoffset, yoffset, null); + + } + else + { + float scale = vncCanvas.getScale(); + int xo = xoffset < 0 ? 0 : xoffset; + int yo = yoffset < 0 ? 0 : yoffset; + /* + if (scale == 1 || scale <= 0) + { + */ + int drawWidth = vncCanvas.getVisibleWidth(); + if (drawWidth + xo > data.framebufferwidth) + drawWidth = data.framebufferwidth - xo; + int drawHeight = vncCanvas.getVisibleHeight(); + if (drawHeight + yo > data.framebufferheight) + drawHeight = data.framebufferheight - yo; + + + //canvas.drawBitmap(data.bitmapPixels, offset(xo, yo), data.framebufferwidth, xo, yo, drawWidth, drawHeight, false, null); + + //XXX; for Hardware accelerated surfaces we have to stop using the above deprecated method and use a bitmap-backed method + // this fixes the issue with Nougat Devices displaying black screen for 24bit color mode C24bit + Bitmap bitmapTmp = Bitmap.createBitmap(framebufferwidth, framebufferheight, Config.bitmapConfig); + bitmapTmp.setPixels(bitmapPixels, offset(xo, yo), data.framebufferwidth, 0, 0, drawWidth, drawHeight); + canvas.drawBitmap(bitmapTmp, xo, yo, null); + + /* + } + else + { + int scalewidth = (int)(vncCanvas.getVisibleWidth() / scale + 1); + if (scalewidth + xo > data.framebufferwidth) + scalewidth = data.framebufferwidth - xo; + int scaleheight = (int)(vncCanvas.getVisibleHeight() / scale + 1); + if (scaleheight + yo > data.framebufferheight) + scaleheight = data.framebufferheight - yo; + canvas.drawBitmap(data.bitmapPixels, offset(xo, yo), data.framebufferwidth, xo, yo, scalewidth, scaleheight, false, null); + } + */ + } + if(data.vncCanvas.connection.getUseLocalCursor()) + { + setCursorRect(data.vncCanvas.mouseX, data.vncCanvas.mouseY); + clipRect.set(cursorRect); + if (canvas.clipRect(cursorRect)) + { + drawCursor(canvas); + } + } + } + } + + /** + * Multiply this times total number of pixels to get estimate of process size with all buffers plus + * safety factor + */ + static final int CAPACITY_MULTIPLIER = 7; + + /** + * @param p + * @param c + */ + public FullBufferBitmapData(RfbProto p, VncCanvas c, int capacity) { + super(p, c); + framebufferwidth=rfb.framebufferWidth; + framebufferheight=rfb.framebufferHeight; + bitmapwidth=framebufferwidth; + bitmapheight=framebufferheight; + android.util.Log.i("FBBM", "bitmapsize = ("+bitmapwidth+","+bitmapheight+")"); + bitmapPixels = new int[framebufferwidth * framebufferheight]; + } + + /* (non-Javadoc) + * @see android.androidVNC.AbstractBitmapData#copyRect(android.graphics.Rect, android.graphics.Rect, android.graphics.Paint) + */ + @Override + void copyRect(Rect src, Rect dest, Paint paint) { + // TODO copy rect working? + throw new RuntimeException( "copyrect Not implemented"); + } + + /* (non-Javadoc) + * @see android.androidVNC.AbstractBitmapData#createDrawable() + */ + @Override + AbstractBitmapDrawable createDrawable() { + return new Drawable(this); + } + + /* (non-Javadoc) + * @see android.androidVNC.AbstractBitmapData#drawRect(int, int, int, int, android.graphics.Paint) + */ + @Override + void drawRect(int x, int y, int w, int h, Paint paint) { + int color = paint.getColor(); + int offset = offset(x,y); + if (w > 10) + { + for (int j = 0; j < h; j++, offset += framebufferwidth) + { + Arrays.fill(bitmapPixels, offset, offset + w, color); + } + } + else + { + for (int j = 0; j < h; j++, offset += framebufferwidth - w) + { + for (int k = 0; k < w; k++, offset++) + { + bitmapPixels[offset] = color; + } + } + } + } + + /* (non-Javadoc) + * @see android.androidVNC.AbstractBitmapData#offset(int, int) + */ + @Override + int offset(int x, int y) { + return x + y * framebufferwidth; + } + + /* (non-Javadoc) + * @see android.androidVNC.AbstractBitmapData#scrollChanged(int, int) + */ + @Override + void scrollChanged(int newx, int newy) { + xoffset = newx; + yoffset = newy; + } + + /* (non-Javadoc) + * @see android.androidVNC.AbstractBitmapData#syncScroll() + */ + @Override + void syncScroll() { + // Don't need to do anything here + + } + + /* (non-Javadoc) + * @see android.androidVNC.AbstractBitmapData#updateBitmap(int, int, int, int) + */ + @Override + void updateBitmap(int x, int y, int w, int h) { + // Don't need to do anything here + + } + + /* (non-Javadoc) + * @see android.androidVNC.AbstractBitmapData#validDraw(int, int, int, int) + */ + @Override + boolean validDraw(int x, int y, int w, int h) { + return true; + } + + /* (non-Javadoc) + * @see android.androidVNC.AbstractBitmapData#writeFullUpdateRequest(boolean) + */ + @Override + void writeFullUpdateRequest(boolean incremental) throws IOException { + rfb.writeFramebufferUpdateRequest(0, 0, framebufferwidth, framebufferheight, incremental); + } + +} diff --git a/app/src/main/java/android/androidVNC/InStream.java b/app/src/main/java/android/androidVNC/InStream.java new file mode 100644 index 0000000..cbbda06 --- /dev/null +++ b/app/src/main/java/android/androidVNC/InStream.java @@ -0,0 +1,155 @@ +/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved. + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +// +// rdr::InStream marshalls data from a buffer stored in RDR (RFB Data +// Representation). +// +package android.androidVNC; + + +abstract public class InStream { + + // check() ensures there is buffer data for at least one item of size + // itemSize bytes. Returns the number of items in the buffer (up to a + // maximum of nItems). + + public final int check(int itemSize, int nItems) throws Exception { + if (ptr + itemSize * nItems > end) { + if (ptr + itemSize > end) + return overrun(itemSize, nItems); + + nItems = (end - ptr) / itemSize; + } + return nItems; + } + + public final void check(int itemSize) throws Exception { + if (ptr + itemSize > end) + overrun(itemSize, 1); + } + + // readU/SN() methods read unsigned and signed N-bit integers. + + public final int readS8() throws Exception { + check(1); return b[ptr++]; + } + + public final int readS16() throws Exception { + check(2); int b0 = b[ptr++]; + int b1 = b[ptr++] & 0xff; return b0 << 8 | b1; + } + + public final int readS32() throws Exception { + check(4); int b0 = b[ptr++]; + int b1 = b[ptr++] & 0xff; + int b2 = b[ptr++] & 0xff; + int b3 = b[ptr++] & 0xff; + return b0 << 24 | b1 << 16 | b2 << 8 | b3; + } + + public final int readU8() throws Exception { + return readS8() & 0xff; + } + + public final int readU16() throws Exception { + return readS16() & 0xffff; + } + + public final int readU32() throws Exception { + return readS32() & 0xffffffff; + } + + public final void skip(int bytes) throws Exception { + while (bytes > 0) { + int n = check(1, bytes); + ptr += n; + bytes -= n; + } + } + + // readBytes() reads an exact number of bytes into an array at an offset. + + public void readBytes(byte[] data, int offset, int length) throws Exception { + int offsetEnd = offset + length; + while (offset < offsetEnd) { + int n = check(1, offsetEnd - offset); + System.arraycopy(b, ptr, data, offset, n); + ptr += n; + offset += n; + } + } + + // readOpaqueN() reads a quantity "without byte-swapping". Because java has + // no byte-ordering, we just use big-endian. + + public final int readOpaque8() throws Exception { + return readU8(); + } + + public final int readOpaque16() throws Exception { + return readU16(); + } + + public final int readOpaque32() throws Exception { + return readU32(); + } + + public final int readOpaque24A() throws Exception { + check(3); int b0 = b[ptr++]; + int b1 = b[ptr++]; int b2 = b[ptr++]; + return b0 << 24 | b1 << 16 | b2 << 8; + } + + public final int readOpaque24B() throws Exception { + check(3); int b0 = b[ptr++]; + int b1 = b[ptr++]; int b2 = b[ptr++]; + return b0 << 16 | b1 << 8 | b2; + } + + // pos() returns the position in the stream. + + abstract public int pos(); + + // bytesAvailable() returns true if at least one byte can be read from the + // stream without blocking. i.e. if false is returned then readU8() would + // block. + + public boolean bytesAvailable() { return end != ptr; } + + // getbuf(), getptr(), getend() and setptr() are "dirty" methods which allow + // you to manipulate the buffer directly. This is useful for a stream which + // is a wrapper around an underlying stream. + + public final byte[] getbuf() { return b; } + public final int getptr() { return ptr; } + public final int getend() { return end; } + public final void setptr(int p) { ptr = p; } + + // overrun() is implemented by a derived class to cope with buffer overrun. + // It ensures there are at least itemSize bytes of buffer data. Returns + // the number of items in the buffer (up to a maximum of nItems). itemSize + // is supposed to be "small" (a few bytes). + + abstract protected int overrun(int itemSize, int nItems) throws Exception; + + protected InStream() {} + protected byte[] b; + protected int ptr; + protected int end; +} diff --git a/app/src/main/java/android/androidVNC/LargeBitmapData.java b/app/src/main/java/android/androidVNC/LargeBitmapData.java new file mode 100644 index 0000000..68f7613 --- /dev/null +++ b/app/src/main/java/android/androidVNC/LargeBitmapData.java @@ -0,0 +1,319 @@ +/** + * Copyright (C) 2009 Michael A. MacDonald + */ +package android.androidVNC; + +import java.io.IOException; + +import com.antlersoft.android.drawing.OverlappingCopy; +import com.antlersoft.android.drawing.RectList; +import com.antlersoft.util.ObjectPool; +import com.vectras.qemu.Config; + +import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.Paint; +import android.graphics.Rect; + +/** + * @author Michael A. MacDonald + * + */ +class LargeBitmapData extends AbstractBitmapData { + + /** + * Multiply this times total number of pixels to get estimate of process size with all buffers plus + * safety factor + */ + static final int CAPACITY_MULTIPLIER = 21; + + int xoffset; + int yoffset; + int scrolledToX; + int scrolledToY; + private Rect bitmapRect; + private Paint defaultPaint; + private RectList invalidList; + private RectList pendingList; + + /** + * Pool of temporary rectangle objects. Need to synchronize externally access from + * multiple threads. + */ + private static ObjectPool rectPool = new ObjectPool() { + + /* (non-Javadoc) + * @see com.antlersoft.util.ObjectPool#itemForPool() + */ + @Override + protected Rect itemForPool() { + return new Rect(); + } + }; + + class LargeBitmapDrawable extends AbstractBitmapDrawable + { + LargeBitmapDrawable() + { + super(LargeBitmapData.this); + } + /* (non-Javadoc) + * @see android.graphics.drawable.DrawableContainer#draw(android.graphics.Canvas) + */ + @Override + public void draw(Canvas canvas) { + //android.util.Log.i("LBM", "Drawing "+xoffset+" "+yoffset); + int xoff, yoff; + synchronized ( LargeBitmapData.this ) + { + xoff=xoffset; + yoff=yoffset; + } + draw(canvas, xoff, yoff); + } + } + + /** + * + * @param p Protocol implementation + * @param c View that will display screen + * @param displayWidth + * @param displayHeight + * @param capacity Max process heap size in bytes + */ + LargeBitmapData(RfbProto p, VncCanvas c, int displayWidth, int displayHeight, int capacity) + { + super(p,c); + double scaleMultiplier = Math.sqrt((double)(capacity * 1024 * 1024) / (double)(CAPACITY_MULTIPLIER * framebufferwidth * framebufferheight)); + if (scaleMultiplier > 1) + scaleMultiplier = 1; + bitmapwidth=(int)((double)framebufferwidth * scaleMultiplier); + if (bitmapwidth < displayWidth) + bitmapwidth = displayWidth; + bitmapheight=(int)((double)framebufferheight * scaleMultiplier); + if (bitmapheight < displayHeight) + bitmapheight = displayHeight; + android.util.Log.i("LBM", "bitmapsize = ("+bitmapwidth+","+bitmapheight+")"); + mbitmap = Bitmap.createBitmap(bitmapwidth, bitmapheight, Config.bitmapConfig); + memGraphics = new Canvas(mbitmap); + bitmapPixels = new int[bitmapwidth * bitmapheight]; + invalidList = new RectList(rectPool); + pendingList = new RectList(rectPool); + bitmapRect=new Rect(0,0,bitmapwidth,bitmapheight); + defaultPaint = new Paint(); + } + + @Override + AbstractBitmapDrawable createDrawable() + { + return new LargeBitmapDrawable(); + } + + /* (non-Javadoc) + * @see android.androidVNC.AbstractBitmapData#copyRect(android.graphics.Rect, android.graphics.Rect, android.graphics.Paint) + */ + @Override + void copyRect(Rect src, Rect dest, Paint paint) { + // TODO copy rect working? + throw new RuntimeException( "copyrect Not implemented"); + } + + /* (non-Javadoc) + * @see android.androidVNC.AbstractBitmapData#drawRect(int, int, int, int, android.graphics.Paint) + */ + @Override + void drawRect(int x, int y, int w, int h, Paint paint) { + x-=xoffset; + y-=yoffset; + memGraphics.drawRect(x, y, x+w, y+h, paint); + } + + /* (non-Javadoc) + * @see android.androidVNC.AbstractBitmapData#offset(int, int) + */ + @Override + int offset(int x, int y) { + return (y - yoffset) * bitmapwidth + x - xoffset; + } + + /* (non-Javadoc) + * @see android.androidVNC.AbstractBitmapData#scrollChanged(int, int) + */ + @Override + synchronized void scrollChanged(int newx, int newy) { + //android.util.Log.i("LBM","scroll "+newx+" "+newy); + int newScrolledToX = scrolledToX; + int newScrolledToY = scrolledToY; + int visibleWidth = vncCanvas.getVisibleWidth(); + int visibleHeight = vncCanvas.getVisibleHeight(); + if (newx - xoffset < 0 ) + { + newScrolledToX = newx + visibleWidth / 2 - bitmapwidth / 2; + if (newScrolledToX < 0) + newScrolledToX = 0; + } + else if (newx - xoffset + visibleWidth > bitmapwidth) + { + newScrolledToX = newx + visibleWidth / 2 - bitmapwidth / 2; + if (newScrolledToX + bitmapwidth > framebufferwidth) + newScrolledToX = framebufferwidth - bitmapwidth; + } + if (newy - yoffset < 0 ) + { + newScrolledToY = newy + visibleHeight / 2 - bitmapheight / 2; + if (newScrolledToY < 0) + newScrolledToY = 0; + } + else if (newy - yoffset + visibleHeight > bitmapheight) + { + newScrolledToY = newy + visibleHeight / 2 - bitmapheight / 2; + if (newScrolledToY + bitmapheight > framebufferheight) + newScrolledToY = framebufferheight - bitmapheight; + } + if (newScrolledToX != scrolledToX || newScrolledToY != scrolledToY) + { + scrolledToX = newScrolledToX; + scrolledToY = newScrolledToY; + if ( waitingForInput) + syncScroll(); + } + } + + /* (non-Javadoc) + * @see android.androidVNC.AbstractBitmapData#updateBitmap(int, int, int, int) + */ + @Override + void updateBitmap(int x, int y, int w, int h) { + mbitmap.setPixels(bitmapPixels, offset(x,y), bitmapwidth, x-xoffset, y-yoffset, w, h); + } + + /* (non-Javadoc) + * @see android.androidVNC.AbstractBitmapData#validDraw(int, int, int, int) + */ + @Override + synchronized boolean validDraw(int x, int y, int w, int h) { + //android.util.Log.i("LBM", "Validate Drawing "+x+" "+y+" "+w+" "+h+" "+xoffset+" "+yoffset+" "+(x-xoffset>=0 && x-xoffset+w<=bitmapwidth && y-yoffset>=0 && y-yoffset+h<=bitmapheight)); + boolean result = x-xoffset>=0 && x-xoffset+w<=bitmapwidth && y-yoffset>=0 && y-yoffset+h<=bitmapheight; + ObjectPool.Entry entry = rectPool.reserve(); + Rect r = entry.get(); + r.set(x, y, x+w, y+h); + pendingList.subtract(r); + if ( ! result) + { + invalidList.add(r); + } + else + invalidList.subtract(r); + rectPool.release(entry); + return result; + } + + /* (non-Javadoc) + * @see android.androidVNC.AbstractBitmapData#writeFullUpdateRequest(boolean) + */ + @Override + synchronized void writeFullUpdateRequest(boolean incremental) throws IOException { + if (! incremental) { + ObjectPool.Entry entry = rectPool.reserve(); + Rect r = entry.get(); + r.left=xoffset; + r.top=yoffset; + r.right=xoffset + bitmapwidth; + r.bottom=yoffset + bitmapheight; + pendingList.add(r); + invalidList.add(r); + rectPool.release(entry); + } + rfb.writeFramebufferUpdateRequest(xoffset, yoffset, bitmapwidth, bitmapheight, incremental); + } + + /* (non-Javadoc) + * @see android.androidVNC.AbstractBitmapData#syncScroll() + */ + @Override + synchronized void syncScroll() { + + int deltaX = xoffset - scrolledToX; + int deltaY = yoffset - scrolledToY; + xoffset=scrolledToX; + yoffset=scrolledToY; + bitmapRect.top=scrolledToY; + bitmapRect.bottom=scrolledToY+bitmapheight; + bitmapRect.left=scrolledToX; + bitmapRect.right=scrolledToX+bitmapwidth; + invalidList.intersect(bitmapRect); + if ( deltaX != 0 || deltaY != 0) + { + boolean didOverlapping = false; + if (Math.abs(deltaX) < bitmapwidth && Math.abs(deltaY) < bitmapheight) { + ObjectPool.Entry sourceEntry = rectPool.reserve(); + ObjectPool.Entry addedEntry = rectPool.reserve(); + try + { + Rect added = addedEntry.get(); + Rect sourceRect = sourceEntry.get(); + sourceRect.set(deltaX<0 ? -deltaX : 0, + deltaY<0 ? -deltaY : 0, + deltaX<0 ? bitmapwidth : bitmapwidth - deltaX, + deltaY < 0 ? bitmapheight : bitmapheight - deltaY); + if (! invalidList.testIntersect(sourceRect)) { + didOverlapping = true; + OverlappingCopy.Copy(mbitmap, memGraphics, defaultPaint, sourceRect, deltaX + sourceRect.left, deltaY + sourceRect.top, rectPool); + // Write request for side pixels + if (deltaX != 0) { + added.left = deltaX < 0 ? bitmapRect.right + deltaX : bitmapRect.left; + added.right = added.left + Math.abs(deltaX); + added.top = bitmapRect.top; + added.bottom = bitmapRect.bottom; + invalidList.add(added); + } + if (deltaY != 0) { + added.left = deltaX < 0 ? bitmapRect.left : bitmapRect.left + deltaX; + added.top = deltaY < 0 ? bitmapRect.bottom + deltaY : bitmapRect.top; + added.right = added.left + bitmapwidth - Math.abs(deltaX); + added.bottom = added.top + Math.abs(deltaY); + invalidList.add(added); + } + } + } + finally { + rectPool.release(addedEntry); + rectPool.release(sourceEntry); + } + } + if (! didOverlapping) + { + try + { + //android.util.Log.i("LBM","update req "+xoffset+" "+yoffset); + mbitmap.eraseColor(Color.GREEN); + writeFullUpdateRequest(false); + } + catch ( IOException ioe) + { + // TODO log this + } + } + } + int size = pendingList.getSize(); + for (int i=0; i { + public int keySym; + int mouseButtons; + int keyEvent; + String name; + boolean isMouse; + boolean isKeyEvent; + + MetaKeyBase(int mouseButtons, String name) + { + this.mouseButtons = mouseButtons; + this.name = name; + this.isMouse = true; + this.isKeyEvent = false; + } + + MetaKeyBase(String name, int keySym, int keyEvent) + { + this.name = name; + this.keySym = keySym; + this.keyEvent = keyEvent; + this.isMouse = false; + this.isKeyEvent = true; + } + + MetaKeyBase(String name, int keySym) + { + this.name = name; + this.keySym = keySym; + this.isMouse = false; + this.isKeyEvent = false; + } + + /* (non-Javadoc) + * @see java.lang.Comparable#compareTo(java.lang.Object) + */ + @Override + public int compareTo(MetaKeyBase another) { + return name.compareTo(another.name); + } +} diff --git a/app/src/main/java/android/androidVNC/MetaKeyBean.java b/app/src/main/java/android/androidVNC/MetaKeyBean.java new file mode 100644 index 0000000..c5d82b5 --- /dev/null +++ b/app/src/main/java/android/androidVNC/MetaKeyBean.java @@ -0,0 +1,267 @@ +/** + * Copyright (C) 2009 Michael A. MacDonald + */ +package android.androidVNC; + +import java.util.ArrayList; +import java.util.HashMap; + +import android.view.KeyEvent; + +/** + * @author Michael A. MacDonald + * + */ +public class MetaKeyBean { + int keySym; + int metaFlags; + + static final ArrayList allKeys; + static final String[] allKeysNames; + public static final HashMap keysByKeyCode; + static final HashMap keysByMouseButton; + static final HashMap keysByKeySym; + static final MetaKeyBean keyCtrlAltDel; + static final MetaKeyBean keyCtrlC; + static final MetaKeyBean keyArrowLeft; + static final MetaKeyBean keyArrowRight; + static final MetaKeyBean keyArrowUp; + static final MetaKeyBean keyArrowDown; + + static { + allKeys = new ArrayList(); + + allKeys.add(new MetaKeyBase("Hangul", 0xff31)); + allKeys.add(new MetaKeyBase("Hangul_Start", 0xff32)); + allKeys.add(new MetaKeyBase("Hangul_End", 0xff33)); + allKeys.add(new MetaKeyBase("Hangul_Hanja", 0xff34)); + allKeys.add(new MetaKeyBase("Kana_Shift", 0xff2e)); + allKeys.add(new MetaKeyBase("Right_Alt", 0xffea)); + + allKeys.add(new MetaKeyBase(VncCanvas.MOUSE_BUTTON_LEFT, "Mouse Left")); + allKeys.add(new MetaKeyBase(VncCanvas.MOUSE_BUTTON_MIDDLE, + "Mouse Middle")); + allKeys.add(new MetaKeyBase(VncCanvas.MOUSE_BUTTON_RIGHT, "Mouse Right")); + allKeys.add(new MetaKeyBase(VncCanvas.MOUSE_BUTTON_SCROLL_DOWN, + "Mouse Scroll Down")); + allKeys.add(new MetaKeyBase(VncCanvas.MOUSE_BUTTON_SCROLL_UP, + "Mouse Scroll Up")); + + allKeys.add(new MetaKeyBase("Home", 0xFF50)); + allKeys.add(new MetaKeyBase("Arrow Left", 0xFF51)); + allKeys.add(new MetaKeyBase("Arrow Up", 0xFF52)); + allKeys.add(new MetaKeyBase("Arrow Right", 0xFF53)); + allKeys.add(new MetaKeyBase("Arrow Down", 0xFF54)); + allKeys.add(new MetaKeyBase("Page Up", 0xFF55)); + allKeys.add(new MetaKeyBase("Page Down", 0xFF56)); + allKeys.add(new MetaKeyBase("End", 0xFF57)); + allKeys.add(new MetaKeyBase("Insert", 0xFF63)); + allKeys.add(new MetaKeyBase("Delete", 0xFFFF, KeyEvent.KEYCODE_DEL)); + allKeys.add(new MetaKeyBase("Num Lock", 0xFF7F)); + allKeys.add(new MetaKeyBase("Break", 0xFF6b)); + allKeys.add(new MetaKeyBase("Scroll Lock", 0xFF14)); + allKeys.add(new MetaKeyBase("Print Scrn", 0xFF15)); + allKeys.add(new MetaKeyBase("Escape", 0xFF1B)); + allKeys.add(new MetaKeyBase("Enter", 0xFF0D, KeyEvent.KEYCODE_ENTER)); + allKeys.add(new MetaKeyBase("Tab", 0xFF09, KeyEvent.KEYCODE_TAB)); + allKeys.add(new MetaKeyBase("BackSpace", 0xFF08)); + allKeys.add(new MetaKeyBase("Space", 0x020, KeyEvent.KEYCODE_SPACE)); + + StringBuilder sb = new StringBuilder(" "); + for (int i = 0; i < 26; i++) { + sb.setCharAt(0, (char) ('A' + i)); + allKeys.add(new MetaKeyBase(sb.toString(), 'a' + i, + KeyEvent.KEYCODE_A + i)); + } + + for (int i = 0; i < 10; i++) { + sb.setCharAt(0, (char) ('0' + i)); + allKeys.add(new MetaKeyBase(sb.toString(), '0' + i, + KeyEvent.KEYCODE_0 + i)); + } + + for (int i = 0; i < 12; i++) { + sb.setLength(0); + sb.append('F'); + if (i < 9) + sb.append(' '); + sb.append(Integer.toString(i + 1)); + allKeys.add(new MetaKeyBase(sb.toString(), 0xFFBE + i)); + } + + java.util.Collections.sort(allKeys); + allKeysNames = new String[allKeys.size()]; + keysByKeyCode = new HashMap(); + keysByMouseButton = new HashMap(); + keysByKeySym = new HashMap(); + for (int i = 0; i < allKeysNames.length; ++i) { + MetaKeyBase b = allKeys.get(i); + allKeysNames[i] = b.name; + if (b.isKeyEvent) + keysByKeyCode.put(b.keyEvent, b); + if (b.isMouse) + keysByMouseButton.put(b.mouseButtons, b); + else + keysByKeySym.put(b.keySym, b); + } + keyCtrlAltDel = new MetaKeyBean(0, VncCanvas.CTRL_MASK + | VncCanvas.ALT_MASK, keysByKeyCode.get(KeyEvent.KEYCODE_DEL)); + keyCtrlC = new MetaKeyBean(0, VncCanvas.CTRL_MASK, + keysByKeyCode.get(KeyEvent.KEYCODE_C)); + keyArrowLeft = new MetaKeyBean(0, 0, keysByKeySym.get(0xFF51)); + keyArrowUp = new MetaKeyBean(0, 0, keysByKeySym.get(0xFF52)); + keyArrowRight = new MetaKeyBean(0, 0, keysByKeySym.get(0xFF53)); + keyArrowDown = new MetaKeyBean(0, 0, keysByKeySym.get(0xFF54)); + } + + private boolean _regenDesc; + private boolean mouseClick; + + MetaKeyBean() { + } + + MetaKeyBean(MetaKeyBean toCopy) { + _regenDesc = true; + if (toCopy.isMouseClick()) + setMouseButtons(toCopy.getMouseButtons()); + else + setKeySym(toCopy.getKeySym()); + setMetaListId(toCopy.getMetaListId()); + setMetaFlags(toCopy.getMetaFlags()); + } + + private void setMetaListId(Object metaListId) { + + + } + + private Object getMetaListId() { + + return null; + } + + MetaKeyBean(long listId, int metaFlags, MetaKeyBase base) { + + setKeyBase(base); + setMetaFlags(metaFlags); + _regenDesc = true; + } + + public String getKeyDesc() { + if (_regenDesc) { + synchronized (this) { + if (_regenDesc) { + StringBuilder sb = new StringBuilder(); + int meta = getMetaFlags(); + if (0 != (meta & VncCanvas.SHIFT_MASK)) { + sb.append("Shift"); + } + if (0 != (meta & VncCanvas.CTRL_MASK)) { + if (sb.length() > 0) + sb.append('-'); + sb.append("Ctrl"); + } + if (0 != (meta & VncCanvas.ALT_MASK)) { + if (sb.length() > 0) + sb.append('-'); + sb.append("Alt"); + } + if (sb.length() > 0) + sb.append(' '); + MetaKeyBase base; + if (isMouseClick()) + base = keysByMouseButton.get(getMouseButtons()); + else + base = keysByKeySym.get(getKeySym()); + sb.append(base.name); + setKeyDesc(sb.toString()); + } + } + } + return getKeyDesc(); + } + + public void setKeyDesc(String arg_keyDesc) { + _regenDesc = false; + } + + public void setKeySym(int arg_keySym) { + if (arg_keySym != getKeySym() || isMouseClick()) { + setMouseClick(false); + _regenDesc = true; + + } + this.keySym = arg_keySym ; + } + + int getKeySym() { + + return keySym; + } + + /* + * (non-Javadoc) + * + * @see android.androidVNC.AbstractMetaKeyBean#setMetaFlags(int) + */ + public void setMetaFlags(int arg_metaFlags) { + if (arg_metaFlags != getMetaFlags()) { + _regenDesc = true; + } + this.metaFlags = arg_metaFlags; + } + + int getMetaFlags() { + + return this.metaFlags; + } + + /* + * (non-Javadoc) + * + * @see android.androidVNC.AbstractMetaKeyBean#setMouseButtons(int) + */ + public void setMouseButtons(int arg_mouseButtons) { + if (arg_mouseButtons != getMouseButtons() || !isMouseClick()) { + setMouseClick(true); + _regenDesc = true; + } + } + + private void setMouseClick(boolean b) { + + this.mouseClick = b; + } + + boolean isMouseClick() { + + return false; + } + + int getMouseButtons() { + + return 0; + } + + void setKeyBase(MetaKeyBase base) { + if (base.isMouse) { + setMouseButtons(base.mouseButtons); + } else { + setKeySym(base.keySym); + } + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object o) { + if (o instanceof MetaKeyBean) { + return getKeyDesc().equals(((MetaKeyBean) o).getKeyDesc()); + } + return false; + } + +} diff --git a/app/src/main/java/android/androidVNC/MetaList.java b/app/src/main/java/android/androidVNC/MetaList.java new file mode 100644 index 0000000..f4b3d89 --- /dev/null +++ b/app/src/main/java/android/androidVNC/MetaList.java @@ -0,0 +1,77 @@ +// This class was generated from android.androidVNC.IMetaList by a tool +// Do not edit this file directly! PLX THX +package android.androidVNC; + +public class MetaList { + + public static final String GEN_TABLE_NAME = "META_LIST"; + public static final int GEN_COUNT = 2; + + // Field constants + public static final String GEN_FIELD__ID = "_id"; + public static final int GEN_ID__ID = 0; + public static final String GEN_FIELD_NAME = "NAME"; + public static final int GEN_ID_NAME = 1; + + // SQL Command for creating the table + public static String GEN_CREATE = "CREATE TABLE META_LIST (" + + "_id INTEGER PRIMARY KEY AUTOINCREMENT," + + "NAME TEXT" + + ")"; + + // Members corresponding to defined fields + private long gen__Id; + private java.lang.String gen_name; + + + public String Gen_tableName() { return GEN_TABLE_NAME; } + + // Field accessors + public long get_Id() { return gen__Id; } + public void set_Id(long arg__Id) { gen__Id = arg__Id; } + public java.lang.String getName() { return gen_name; } + public void setName(java.lang.String arg_name) { gen_name = arg_name; } + + public android.content.ContentValues Gen_getValues() { + android.content.ContentValues values=new android.content.ContentValues(); + values.put(GEN_FIELD__ID,Long.toString(this.gen__Id)); + values.put(GEN_FIELD_NAME,this.gen_name); + return values; + } + + /** + * Return an array that gives the column index in the cursor for each field defined + * @param cursor Database cursor over some columns, possibly including this table + * @return array of column indices; -1 if the column with that id is not in cursor + */ + public int[] Gen_columnIndices(android.database.Cursor cursor) { + int[] result=new int[GEN_COUNT]; + result[0] = cursor.getColumnIndex(GEN_FIELD__ID); + // Make compatible with database generated by older version of plugin with uppercase column name + if (result[0] == -1) { + result[0] = cursor.getColumnIndex("_ID"); + } + result[1] = cursor.getColumnIndex(GEN_FIELD_NAME); + return result; + } + + /** + * Populate one instance from a cursor + */ + public void Gen_populate(android.database.Cursor cursor,int[] columnIndices) { + if ( columnIndices[GEN_ID__ID] >= 0 && ! cursor.isNull(columnIndices[GEN_ID__ID])) { + gen__Id = cursor.getLong(columnIndices[GEN_ID__ID]); + } + if ( columnIndices[GEN_ID_NAME] >= 0 && ! cursor.isNull(columnIndices[GEN_ID_NAME])) { + gen_name = cursor.getString(columnIndices[GEN_ID_NAME]); + } + } + + /** + * Populate one instance from a ContentValues + */ + public void Gen_populate(android.content.ContentValues values) { + gen__Id = values.getAsLong(GEN_FIELD__ID); + gen_name = values.getAsString(GEN_FIELD_NAME); + } +} diff --git a/app/src/main/java/android/androidVNC/MouseMover.java b/app/src/main/java/android/androidVNC/MouseMover.java new file mode 100644 index 0000000..618ab09 --- /dev/null +++ b/app/src/main/java/android/androidVNC/MouseMover.java @@ -0,0 +1,54 @@ +/** + * Copyright 2010 Michael A. MacDonald + */ +package android.androidVNC; + +import android.os.Handler; +import android.os.SystemClock; +import android.view.MotionEvent; + +/** + * Specialization of panner that moves the mouse instead of panning the screen + * + * @author Michael A. MacDonald + * + */ +class MouseMover extends Panner { + + public MouseMover(VncCanvasActivity act, Handler hand) { + super(act, hand); + } + + /* (non-Javadoc) + * @see java.lang.Runnable#run() + */ + @Override + public void run() { + long interval = SystemClock.uptimeMillis() - lastSent; + lastSent += interval; + double scale = (double)interval / 50.0; + VncCanvas canvas = activity.vncCanvas; + //Log.v(TAG, String.format("panning %f %d %d", scale, (int)((double)velocity.x * scale), (int)((double)velocity.y * scale))); + if ( canvas.processPointerEvent((int)(canvas.mouseX + ((double)velocity.x * scale)), + (int)(canvas.mouseY + ((double)velocity.y * scale)), + MotionEvent.ACTION_MOVE, 0, + false, false, false, false)) + { + if (updater.updateVelocity(velocity, interval)) + { + handler.postDelayed(this, 50); + } + else + { + //Log.v(TAG, "Updater requests stop"); + stop(); + } + } + else + { + //Log.v(TAG, "Panning failed"); + stop(); + } + } + +} diff --git a/app/src/main/java/android/androidVNC/OneToOneScaling.java b/app/src/main/java/android/androidVNC/OneToOneScaling.java new file mode 100644 index 0000000..5c6f0b8 --- /dev/null +++ b/app/src/main/java/android/androidVNC/OneToOneScaling.java @@ -0,0 +1,57 @@ +/** + * Copyright (C) 2009 Michael A. MacDonald + */ +package android.androidVNC; + +import android.widget.ImageView.ScaleType; + +import com.vectras.vm.R; + +/** + * @author Michael A. MacDonald + */ +class OneToOneScaling extends AbstractScaling { + + /** + * @param id + * @param scaleType + */ + public OneToOneScaling() { + super(R.id.itemOneToOne,ScaleType.CENTER); + } + + /* (non-Javadoc) + * @see android.androidVNC.AbstractScaling#getDefaultHandlerId() + */ + @Override + int getDefaultHandlerId() { + return R.id.itemInputTouchPanTrackballMouse; + } + + /* (non-Javadoc) + * @see android.androidVNC.AbstractScaling#isAbleToPan() + */ + @Override + boolean isAbleToPan() { + return true; + } + + /* (non-Javadoc) + * @see android.androidVNC.AbstractScaling#isValidInputMode(int) + */ + @Override + boolean isValidInputMode(int mode) { + return mode != R.id.itemInputFitToScreen; + } + + /* (non-Javadoc) + * @see android.androidVNC.AbstractScaling#setScaleTypeForActivity(android.androidVNC.VncCanvasActivity) + */ + @Override + public void setScaleTypeForActivity(VncCanvasActivity activity) { + super.setScaleTypeForActivity(activity); + activity.vncCanvas.scrollToAbsolute(); + activity.vncCanvas.pan(0,0); + } + +} diff --git a/app/src/main/java/android/androidVNC/Panner.java b/app/src/main/java/android/androidVNC/Panner.java new file mode 100644 index 0000000..4298f1a --- /dev/null +++ b/app/src/main/java/android/androidVNC/Panner.java @@ -0,0 +1,104 @@ +/** + * Copyright (C) 2009 Michael A. MacDonald + */ +package android.androidVNC; + +import android.graphics.PointF; +import android.os.Handler; +import android.os.SystemClock; + +/** + * Handles panning the screen continuously over a period of time + * @author Michael A. MacDonald + */ +class Panner implements Runnable { + + VncCanvasActivity activity; + Handler handler; + PointF velocity; + long lastSent; + VelocityUpdater updater; + + private static final String TAG = "PANNER"; + + /** + * Specify how the panning velocity changes over time + * @author Michael A. MacDonald + */ + interface VelocityUpdater { + /** + * Called approximately every 50 ms to update the velocity of panning + * @param p X and Y components to update + * @param interval Milliseconds since last update + * @return False if the panning should stop immediately; true otherwise + */ + boolean updateVelocity(PointF p, long interval); + } + + static class DefaultUpdater implements VelocityUpdater { + + static DefaultUpdater instance = new DefaultUpdater(); + + /** + * Don't change velocity + */ + @Override + public boolean updateVelocity(PointF p, long interval) { + return true; + } + + } + + Panner(VncCanvasActivity act, Handler hand) { + activity = act; + velocity = new PointF(); + handler = hand; + } + + void stop() + { + handler.removeCallbacks(this); + } + + void start(float xv, float yv, VelocityUpdater update) + { + if (update == null) + update = DefaultUpdater.instance; + updater = update; + velocity.x = xv; + velocity.y = yv; + //Log.v(TAG, String.format("pan start %f %f", velocity.x, velocity.y)); + lastSent = SystemClock.uptimeMillis(); + + handler.postDelayed(this, 50); + } + + /* (non-Javadoc) + * @see java.lang.Runnable#run() + */ + @Override + public void run() { + long interval = SystemClock.uptimeMillis() - lastSent; + lastSent += interval; + double scale = (double)interval / 50.0; + //Log.v(TAG, String.format("panning %f %d %d", scale, (int)((double)velocity.x * scale), (int)((double)velocity.y * scale))); + if ( activity.vncCanvas.pan((int)((double)velocity.x * scale), (int)((double)velocity.y * scale))) + { + if (updater.updateVelocity(velocity, interval)) + { + handler.postDelayed(this, 50); + } + else + { + //Log.v(TAG, "Updater requests stop"); + stop(); + } + } + else + { + //Log.v(TAG, "Panning failed"); + stop(); + } + } + +} diff --git a/app/src/main/java/android/androidVNC/RepeaterDialog.java b/app/src/main/java/android/androidVNC/RepeaterDialog.java new file mode 100644 index 0000000..b33e0d5 --- /dev/null +++ b/app/src/main/java/android/androidVNC/RepeaterDialog.java @@ -0,0 +1,59 @@ +/** + * + */ +package android.androidVNC; + +import android.app.Activity; +import android.app.Dialog; +import android.os.Bundle; +import android.text.Html; +import android.view.View; +import android.widget.Button; +import android.widget.EditText; +import android.widget.TextView; + +import com.vectras.vm.R; + +/** + * @author Michael A. MacDonald + * + */ +class RepeaterDialog extends Dialog { + private EditText _repeaterId; + androidVNC _configurationDialog; + + RepeaterDialog(androidVNC context) { + super(context); + setOwnerActivity((Activity)context); + _configurationDialog = context; + } + + /* (non-Javadoc) + * @see android.app.Dialog#onCreate(android.os.Bundle) + */ + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setTitle(R.string.repeater_dialog_title); + + setContentView(R.layout.repeater_dialog); + _repeaterId=(EditText)findViewById(R.id.textRepeaterInfo); + ((TextView)findViewById(R.id.textRepeaterCaption)).setText(Html.fromHtml(getContext().getString(R.string.repeater_caption))); + ((Button)findViewById(R.id.buttonSaveRepeater)).setOnClickListener(new View.OnClickListener() { + + @Override + public void onClick(View v) { + _configurationDialog.updateRepeaterInfo(true, _repeaterId.getText().toString()); + dismiss(); + } + }); + ((Button)findViewById(R.id.buttonClearRepeater)).setOnClickListener(new View.OnClickListener() { + + @Override + public void onClick(View v) { + _configurationDialog.updateRepeaterInfo(false, ""); + dismiss(); + } + }); + } +} diff --git a/app/src/main/java/android/androidVNC/RfbProto.java b/app/src/main/java/android/androidVNC/RfbProto.java new file mode 100644 index 0000000..c9e9b90 --- /dev/null +++ b/app/src/main/java/android/androidVNC/RfbProto.java @@ -0,0 +1,1416 @@ +// +// Copyright (C) 2001-2004 HorizonLive.com, Inc. All Rights Reserved. +// Copyright (C) 2001-2006 Constantin Kaplinsky. All Rights Reserved. +// Copyright (C) 2000 Tridia Corporation. All Rights Reserved. +// Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. +// +// This is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This software is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this software; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. +// + +// +// RfbProto.java +// + +package android.androidVNC; + +import android.net.LocalSocket; +import android.net.LocalSocketAddress; +import android.os.Handler; +import android.os.HandlerThread; +import android.util.Log; + +import com.vectras.qemu.Config; + +import java.io.BufferedInputStream; +import java.io.DataInputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.net.Socket; + +//- import java.awt.*; +//- import java.awt.event.*; +//- import java.util.zip.*; + +/** + * Access the RFB protocol through a socket. + *

+ * This class has no knowledge of the android-specific UI; it sees framebuffer updates + * and input events as defined in the RFB protocol. + * + */ +public class RfbProto { + + final static String TAG = "RfbProto"; + + final static String + versionMsg_3_3 = "RFB 003.003\n", + versionMsg_3_7 = "RFB 003.007\n", + versionMsg_3_8 = "RFB 003.008\n"; + + // Vendor signatures: standard VNC/RealVNC, TridiaVNC, and TightVNC + final static String + StandardVendor = "STDV", + TridiaVncVendor = "TRDV", + TightVncVendor = "TGHT"; + + // Security types + final static int + SecTypeInvalid = 0, + SecTypeNone = 1, + SecTypeVncAuth = 2, + SecTypeTight = 16, + SecTypeUltra34 = 0xfffffffa; + + // Supported tunneling types + final static int + NoTunneling = 0; + final static String + SigNoTunneling = "NOTUNNEL"; + + // Supported authentication types + final static int + AuthNone = 1, + AuthVNC = 2, + AuthUnixLogin = 129, + AuthUltra = 17; + final static String + SigAuthNone = "NOAUTH__", + SigAuthVNC = "VNCAUTH_", + SigAuthUnixLogin = "ULGNAUTH"; + + // VNC authentication results + final static int + VncAuthOK = 0, + VncAuthFailed = 1, + VncAuthTooMany = 2; + + // Server-to-client messages + final static int + FramebufferUpdate = 0, + SetColourMapEntries = 1, + Bell = 2, + ServerCutText = 3, + TextChat = 11; + + // Client-to-server messages + final static int + SetPixelFormat = 0, + FixColourMapEntries = 1, + SetEncodings = 2, + FramebufferUpdateRequest = 3, + KeyboardEvent = 4, + PointerEvent = 5, + ClientCutText = 6; + + // Supported encodings and pseudo-encodings + final static int + EncodingRaw = 0, + EncodingCopyRect = 1, + EncodingRRE = 2, + EncodingCoRRE = 4, + EncodingHextile = 5, + EncodingZlib = 6, + EncodingTight = 7, + EncodingZRLE = 16, + EncodingCompressLevel0 = 0xFFFFFF00, + EncodingQualityLevel0 = 0xFFFFFFE0, + EncodingXCursor = 0xFFFFFF10, + EncodingRichCursor = 0xFFFFFF11, + EncodingPointerPos = 0xFFFFFF18, + EncodingLastRect = 0xFFFFFF20, + EncodingNewFBSize = 0xFFFFFF21; + final static String + SigEncodingRaw = "RAW_____", + SigEncodingCopyRect = "COPYRECT", + SigEncodingRRE = "RRE_____", + SigEncodingCoRRE = "CORRE___", + SigEncodingHextile = "HEXTILE_", + SigEncodingZlib = "ZLIB____", + SigEncodingTight = "TIGHT___", + SigEncodingZRLE = "ZRLE____", + SigEncodingCompressLevel0 = "COMPRLVL", + SigEncodingQualityLevel0 = "JPEGQLVL", + SigEncodingXCursor = "X11CURSR", + SigEncodingRichCursor = "RCHCURSR", + SigEncodingPointerPos = "POINTPOS", + SigEncodingLastRect = "LASTRECT", + SigEncodingNewFBSize = "NEWFBSIZ"; + + final static int MaxNormalEncoding = 255; + + // Contstants used in the Hextile decoder + final static int + HextileRaw = 1, + HextileBackgroundSpecified = 2, + HextileForegroundSpecified = 4, + HextileAnySubrects = 8, + HextileSubrectsColoured = 16; + + // Contstants used in the Tight decoder + final static int TightMinToCompress = 12; + final static int + TightExplicitFilter = 0x04, + TightFill = 0x08, + TightJpeg = 0x09, + TightMaxSubencoding = 0x09, + TightFilterCopy = 0x00, + TightFilterPalette = 0x01, + TightFilterGradient = 0x02; + + // Constants used for UltraVNC chat extension + final static int + CHAT_OPEN = -1, + CHAT_CLOSE = -2, + CHAT_FINISHED = -3; + + String host; + int port; + Socket sock; + DataInputStream is; + LimboOutputStream os; + private OutputStream sos; + + //Limbo: need to send the network operations of the Main UI + // but also use a mechanism like IntentService to keep + // the network message queue intact + class LimboOutputStream { + + OutputStream os; + HandlerThread rfbQueueThread = null; + Handler handler = null; + + public LimboOutputStream(OutputStream sos) { + os = sos; + + rfbQueueThread = new HandlerThread("RfbQueue"); + rfbQueueThread.start(); + handler = new Handler(rfbQueueThread.getLooper()); + } + + public void write(final int data) throws IOException { + final int data0 = data; + + handler.post(new Runnable() { + @Override + public void run() { + try { + sos.write(data0); + } catch (IOException e) { + e.printStackTrace(); + } + } + }); + } + + public void write(final byte[] bytes) throws IOException { + final byte [] buffer0 = java.util.Arrays.copyOf(bytes, bytes.length); + + handler.post(new Runnable() { + @Override + public void run() { + try { + sos.write(buffer0); + } catch (IOException e) { + Log.w(TAG, "Error while sending VNC data"); + if(Config.debug) + e.printStackTrace(); + } + } + }); + } + + public void write(final byte[] buffer, final int offset, final int count) throws IOException { + final byte [] buffer0 = java.util.Arrays.copyOf(buffer, count); + final int offset0 = offset; + final int count0 = count; + + handler.post(new Runnable() { + @Override + public void run() { + try { + sos.write(buffer0, offset0, count0); + } catch (IOException e) { + e.printStackTrace(); + } + } + }); + } + + public void close() { + rfbQueueThread.interrupt(); + handler.removeCallbacks(null); + handler.getLooper().quit(); + } + + } + + DH dh; + long dh_resp; + + //- SessionRecorder rec; + boolean inNormalProtocol = false; + //- VncViewer viewer; + + // Java on UNIX does not call keyPressed() on some keys, for example + // swedish keys To prevent our workaround to produce duplicate + // keypresses on JVMs that actually works, keep track of if + // keyPressed() for a "broken" key was called or not. + boolean brokenKeyPressed = false; + + // This will be set to true on the first framebuffer update + // containing Zlib-, ZRLE- or Tight-encoded data. + boolean wereZlibUpdates = false; + + // This will be set to false if the startSession() was called after + // we have received at least one Zlib-, ZRLE- or Tight-encoded + // framebuffer update. + boolean recordFromBeginning = true; + + // This fields are needed to show warnings about inefficiently saved + // sessions only once per each saved session file. + boolean zlibWarningShown; + boolean tightWarningShown; + + // Before starting to record each saved session, we set this field + // to 0, and increment on each framebuffer update. We don't flush + // the SessionRecorder data into the file before the second update. + // This allows us to write initial framebuffer update with zero + // timestamp, to let the player show initial desktop before + // playback. + int numUpdatesInSession; + + // Measuring network throughput. + boolean timing; + long timeWaitedIn100us; + long timedKbits; + + // Protocol version and TightVNC-specific protocol options. + int serverMajor, serverMinor; + int clientMajor, clientMinor; + boolean protocolTightVNC; + CapsContainer tunnelCaps, authCaps; + CapsContainer serverMsgCaps, clientMsgCaps; + CapsContainer encodingCaps; + + // If true, informs that the RFB socket was closed. + private boolean closed; + + + // + // Constructor. Make TCP connection to RFB server. + // + + LocalSocket localSocket = null; + public static boolean allow_external = false; + + //-RfbProto(String h, int p, VncViewer v) throws IOException { + RfbProto(String h, int p) throws IOException{ + //- viewer = v; + host = h; + port = p; + + /* + if (viewer.socketFactory == null) { + sock = new Socket(host, port); + } else { + try { + Class factoryClass = Class.forName(viewer.socketFactory); + SocketFactory factory = (SocketFactory)factoryClass.newInstance(); + //- if (viewer.inAnApplet) + //- sock = factory.createSocket(host, port, viewer); + //- else + sock = factory.createSocket(host, port, viewer.mainArgs); + } + catch(Exception e) { + e.printStackTrace(); + throw new IOException(e.getMessage()); + } + } */ + //+ + + if(!allow_external) { + localSocket = new LocalSocket(); + String localVNCSocketPath = Config.getLocalVNCSocketPath(); + LocalSocketAddress localSocketAddr = new LocalSocketAddress(localVNCSocketPath, LocalSocketAddress.Namespace.FILESYSTEM); + localSocket.connect(localSocketAddr); + is = new DataInputStream(new BufferedInputStream(localSocket.getInputStream(), + 32768)); + sos = localSocket.getOutputStream(); + + } else { + sock = new Socket(host, port); + is = new DataInputStream(new BufferedInputStream(sock.getInputStream(), + 16384)); + sos = sock.getOutputStream(); + } + + os = new LimboOutputStream(sos); + + timing = false; + timeWaitedIn100us = 5; + timedKbits = 0; + } + + + synchronized void close() { + + try { + os.close(); + } catch (Exception ex) { + ex.printStackTrace(); + } + + try { + sock.close(); + closed = true; + //- System.out.println("RFB socket closed"); + Log.v(TAG, "RFB socket closed"); + /*- + if (rec != null) { + rec.close(); + rec = null; + + } */ + } catch (Exception e) { + e.printStackTrace(); + } + + + } + + synchronized boolean closed() { + return closed; + } + + // + // Read server's protocol version message + // + + void readVersionMsg() throws Exception { + + byte[] b = new byte[12]; + + readFully(b); + + if ((b[0] != 'R') || (b[1] != 'F') || (b[2] != 'B') || (b[3] != ' ') + || (b[4] < '0') || (b[4] > '9') || (b[5] < '0') || (b[5] > '9') + || (b[6] < '0') || (b[6] > '9') || (b[7] != '.') + || (b[8] < '0') || (b[8] > '9') || (b[9] < '0') || (b[9] > '9') + || (b[10] < '0') || (b[10] > '9') || (b[11] != '\n')) + { + Log.i(TAG,new String(b)); + throw new Exception("Host " + host + " port " + port + + " is not an RFB server"); + } + + serverMajor = (b[4] - '0') * 100 + (b[5] - '0') * 10 + (b[6] - '0'); + serverMinor = (b[8] - '0') * 100 + (b[9] - '0') * 10 + (b[10] - '0'); + + if (serverMajor < 3) { + throw new Exception("RFB server does not support protocol version 3"); + } + } + + + // + // Write our protocol version message + // + + synchronized void writeVersionMsg() throws IOException { + clientMajor = 3; + if (serverMajor > 3 || serverMinor >= 8) { + clientMinor = 8; + os.write(versionMsg_3_8.getBytes()); + } else if (serverMinor >= 7) { + clientMinor = 7; + os.write(versionMsg_3_7.getBytes()); + } else { + clientMinor = 3; + os.write(versionMsg_3_3.getBytes()); + } + protocolTightVNC = false; + } + + + // + // Negotiate the authentication scheme. + // + + int negotiateSecurity(int bitPref) throws Exception { + return (clientMinor >= 7) ? + selectSecurityType(bitPref) : readSecurityType(bitPref); + } + + // + // Read security type from the server (protocol version 3.3). + // + + int readSecurityType(int bitPref) throws Exception { + int secType = is.readInt(); + + switch (secType) { + case SecTypeInvalid: + readConnFailedReason(); + return SecTypeInvalid; // should never be executed + case SecTypeNone: + case SecTypeVncAuth: + return secType; + case SecTypeUltra34: + if((bitPref & 1) == 1) + return secType; + throw new Exception("Username required."); + default: + throw new Exception("Unknown security type from RFB server: " + secType); + } + } + + // + // Select security type from the server's list (protocol versions 3.7/3.8). + // + + int selectSecurityType(int bitPref) throws Exception { + int secType = SecTypeInvalid; + + // Read the list of security types. + int nSecTypes = is.readUnsignedByte(); + if (nSecTypes == 0) { + readConnFailedReason(); + return SecTypeInvalid; // should never be executed + } + byte[] secTypes = new byte[nSecTypes]; + readFully(secTypes); + + // Find out if the server supports TightVNC protocol extensions + for (int i = 0; i < nSecTypes; i++) { + if (secTypes[i] == SecTypeTight) { + protocolTightVNC = true; + os.write(SecTypeTight); + return SecTypeTight; + } + } + + // Find first supported security type. + for (int i = 0; i < nSecTypes; i++) { + if (secTypes[i] == SecTypeNone || secTypes[i] == SecTypeVncAuth) { + secType = secTypes[i]; + break; + } + } + + if (secType == SecTypeInvalid) { + throw new Exception("Server did not offer supported security type"); + } else { + os.write(secType); + } + + return secType; + } + + // + // Perform "no authentication". + // + + void authenticateNone() throws Exception { + if (clientMinor >= 8) + readSecurityResult("No authentication"); + } + + // + // Perform standard VNC Authentication. + // + + void authenticateVNC(String pw) throws Exception { + byte[] challenge = new byte[16]; + readFully(challenge); + + if (pw.length() > 8) + pw = pw.substring(0, 8); // Truncate to 8 chars + + // Truncate password on the first zero byte. + int firstZero = pw.indexOf(0); + if (firstZero != -1) + pw = pw.substring(0, firstZero); + + byte[] key = {0, 0, 0, 0, 0, 0, 0, 0}; + System.arraycopy(pw.getBytes(), 0, key, 0, pw.length()); + + DesCipher des = new DesCipher(key); + + des.encrypt(challenge, 0, challenge, 0); + des.encrypt(challenge, 8, challenge, 8); + + os.write(challenge); + + readSecurityResult("VNC authentication"); + } + + // + // Read security result. + // Throws an exception on authentication failure. + // + + void readSecurityResult(String authType) throws Exception { + int securityResult = is.readInt(); + + switch (securityResult) { + case VncAuthOK: + System.out.println(authType + ": success"); + break; + case VncAuthFailed: + if (clientMinor >= 8) + readConnFailedReason(); + throw new Exception(authType + ": failed"); + case VncAuthTooMany: + throw new Exception(authType + ": failed, too many tries"); + default: + throw new Exception(authType + ": unknown result " + securityResult); + } + } + + // + // Read the string describing the reason for a connection failure, + // and throw an exception. + // + + void readConnFailedReason() throws Exception { + int reasonLen = is.readInt(); + byte[] reason = new byte[reasonLen]; + readFully(reason); + String reasonString = new String(reason); + Log.v(TAG, reasonString); + throw new Exception(reasonString); + } + + void prepareDH() throws Exception + { + long gen = is.readLong(); + long mod = is.readLong(); + dh_resp = is.readLong(); + + dh = new DH(gen,mod); + long pub = dh.createInterKey(); + + os.write(DH.longToBytes(pub)); + } + + void authenticateDH(String us,String pw) throws Exception + { + long key = dh.createEncryptionKey(dh_resp); + + DesCipher des = new DesCipher(DH.longToBytes(key)); + + byte user[] = new byte[256]; + byte passwd[] = new byte[64]; + int i; + System.arraycopy(us.getBytes(),0,user,0,us.length()); + if(us.length() < 256) + { + for(i=us.length(); i<256; i++) + { + user[i]=0; + } + } + System.arraycopy(pw.getBytes(),0,passwd,0,pw.length()); + if(pw.length() < 64) + { + for(i=pw.length(); i<64; i++) + { + passwd[i]=0; + } + } + + des.encryptText(user,user,DH.longToBytes(key)); + des.encryptText(passwd,passwd,DH.longToBytes(key)); + + os.write(user); + os.write(passwd); + + readSecurityResult("VNC authentication"); + } + // + // Initialize capability lists (TightVNC protocol extensions). + // + + void initCapabilities() { + tunnelCaps = new CapsContainer(); + authCaps = new CapsContainer(); + serverMsgCaps = new CapsContainer(); + clientMsgCaps = new CapsContainer(); + encodingCaps = new CapsContainer(); + + // Supported authentication methods + authCaps.add(AuthNone, StandardVendor, SigAuthNone, + "No authentication"); + authCaps.add(AuthVNC, StandardVendor, SigAuthVNC, + "Standard VNC password authentication"); + + // Supported encoding types + encodingCaps.add(EncodingCopyRect, StandardVendor, + SigEncodingCopyRect, "Standard CopyRect encoding"); + encodingCaps.add(EncodingRRE, StandardVendor, + SigEncodingRRE, "Standard RRE encoding"); + encodingCaps.add(EncodingCoRRE, StandardVendor, + SigEncodingCoRRE, "Standard CoRRE encoding"); + encodingCaps.add(EncodingHextile, StandardVendor, + SigEncodingHextile, "Standard Hextile encoding"); + encodingCaps.add(EncodingZRLE, StandardVendor, + SigEncodingZRLE, "Standard ZRLE encoding"); + encodingCaps.add(EncodingZlib, TridiaVncVendor, + SigEncodingZlib, "Zlib encoding"); + encodingCaps.add(EncodingTight, TightVncVendor, + SigEncodingTight, "Tight encoding"); + + // Supported pseudo-encoding types + encodingCaps.add(EncodingCompressLevel0, TightVncVendor, + SigEncodingCompressLevel0, "Compression level"); + encodingCaps.add(EncodingQualityLevel0, TightVncVendor, + SigEncodingQualityLevel0, "JPEG quality level"); + encodingCaps.add(EncodingXCursor, TightVncVendor, + SigEncodingXCursor, "X-style cursor shape update"); + encodingCaps.add(EncodingRichCursor, TightVncVendor, + SigEncodingRichCursor, "Rich-color cursor shape update"); + encodingCaps.add(EncodingPointerPos, TightVncVendor, + SigEncodingPointerPos, "Pointer position update"); + encodingCaps.add(EncodingLastRect, TightVncVendor, + SigEncodingLastRect, "LastRect protocol extension"); + encodingCaps.add(EncodingNewFBSize, TightVncVendor, + SigEncodingNewFBSize, "Framebuffer size change"); + } + + // + // Setup tunneling (TightVNC protocol extensions) + // + + void setupTunneling() throws IOException { + int nTunnelTypes = is.readInt(); + if (nTunnelTypes != 0) { + readCapabilityList(tunnelCaps, nTunnelTypes); + + // We don't support tunneling yet. + writeInt(NoTunneling); + } + } + + // + // Negotiate authentication scheme (TightVNC protocol extensions) + // + + int negotiateAuthenticationTight() throws Exception { + int nAuthTypes = is.readInt(); + if (nAuthTypes == 0) + return AuthNone; + + readCapabilityList(authCaps, nAuthTypes); + for (int i = 0; i < authCaps.numEnabled(); i++) { + int authType = authCaps.getByOrder(i); + if (authType == AuthNone || authType == AuthVNC) { + writeInt(authType); + return authType; + } + } + throw new Exception("No suitable authentication scheme found"); + } + + // + // Read a capability list (TightVNC protocol extensions) + // + + void readCapabilityList(CapsContainer caps, int count) throws IOException { + int code; + byte[] vendor = new byte[4]; + byte[] name = new byte[8]; + for (int i = 0; i < count; i++) { + code = is.readInt(); + readFully(vendor); + readFully(name); + caps.enable(new CapabilityInfo(code, vendor, name)); + } + } + + // + // Write a 32-bit integer into the output stream. + // + + byte[] writeIntBuffer = new byte[4]; + void writeInt(int value) throws IOException { + writeIntBuffer[0] = (byte) ((value >> 24) & 0xff); + writeIntBuffer[1] = (byte) ((value >> 16) & 0xff); + writeIntBuffer[2] = (byte) ((value >> 8) & 0xff); + writeIntBuffer[3] = (byte) (value & 0xff); + os.write(writeIntBuffer); + } + + // + // Write the client initialisation message + // + + void writeClientInit() throws IOException { + /*- if (viewer.options.shareDesktop) { + os.write(1); + } else { + os.write(0); + } + viewer.options.disableShareDesktop(); + */ + os.write(0); + } + + + // + // Read the server initialisation message + // + + String desktopName; + public int framebufferWidth, framebufferHeight; + int bitsPerPixel, depth; + boolean bigEndian, trueColour; + int redMax, greenMax, blueMax, redShift, greenShift, blueShift; + + void readServerInit() throws IOException { + framebufferWidth = is.readUnsignedShort(); + framebufferHeight = is.readUnsignedShort(); + bitsPerPixel = is.readUnsignedByte(); + depth = is.readUnsignedByte(); + bigEndian = (is.readUnsignedByte() != 0); + trueColour = (is.readUnsignedByte() != 0); + redMax = is.readUnsignedShort(); + greenMax = is.readUnsignedShort(); + blueMax = is.readUnsignedShort(); + redShift = is.readUnsignedByte(); + greenShift = is.readUnsignedByte(); + blueShift = is.readUnsignedByte(); + byte[] pad = new byte[3]; + readFully(pad); + int nameLength = is.readInt(); + byte[] name = new byte[nameLength]; + readFully(name); + desktopName = new String(name); + + // Read interaction capabilities (TightVNC protocol extensions) + if (protocolTightVNC) { + int nServerMessageTypes = is.readUnsignedShort(); + int nClientMessageTypes = is.readUnsignedShort(); + int nEncodingTypes = is.readUnsignedShort(); + is.readUnsignedShort(); + readCapabilityList(serverMsgCaps, nServerMessageTypes); + readCapabilityList(clientMsgCaps, nClientMessageTypes); + readCapabilityList(encodingCaps, nEncodingTypes); + } + + inNormalProtocol = true; + } + + + // + // Create session file and write initial protocol messages into it. + // + /*- + void startSession(String fname) throws IOException { + rec = new SessionRecorder(fname); + rec.writeHeader(); + rec.write(versionMsg_3_3.getBytes()); + rec.writeIntBE(SecTypeNone); + rec.writeShortBE(framebufferWidth); + rec.writeShortBE(framebufferHeight); + byte[] fbsServerInitMsg = { + 32, 24, 0, 1, 0, + (byte)0xFF, 0, (byte)0xFF, 0, (byte)0xFF, + 16, 8, 0, 0, 0, 0 + }; + rec.write(fbsServerInitMsg); + rec.writeIntBE(desktopName.length()); + rec.write(desktopName.getBytes()); + numUpdatesInSession = 0; + + // FIXME: If there were e.g. ZRLE updates only, that should not + // affect recording of Zlib and Tight updates. So, actually + // we should maintain separate flags for Zlib, ZRLE and + // Tight, instead of one ``wereZlibUpdates'' variable. + // + if (wereZlibUpdates) + recordFromBeginning = false; + + zlibWarningShown = false; + tightWarningShown = false; + } + + // + // Close session file. + // + + void closeSession() throws IOException { + if (rec != null) { + rec.close(); + rec = null; + } + } + */ + + // + // Set new framebuffer size + // + + void setFramebufferSize(int width, int height) { + framebufferWidth = width; + framebufferHeight = height; + } + + + // + // Read the server message type + // + + int readServerMessageType() throws IOException { + int msgType = is.readUnsignedByte(); + + // If the session is being recorded: + /*- + if (rec != null) { + if (msgType == Bell) { // Save Bell messages in session files. + rec.writeByte(msgType); + if (numUpdatesInSession > 0) + rec.flush(); + } + } + */ + + return msgType; + } + + + // + // Read a FramebufferUpdate message + // + + int updateNRects; + + void readFramebufferUpdate() throws IOException { + is.readByte(); + updateNRects = is.readUnsignedShort(); + + // If the session is being recorded: + /*- + if (rec != null) { + rec.writeByte(FramebufferUpdate); + rec.writeByte(0); + rec.writeShortBE(updateNRects); + } + */ + + numUpdatesInSession++; + } + + // Read a FramebufferUpdate rectangle header + + int updateRectX, updateRectY, updateRectW, updateRectH, updateRectEncoding; + + void readFramebufferUpdateRectHdr() throws Exception { + updateRectX = is.readUnsignedShort(); + updateRectY = is.readUnsignedShort(); + updateRectW = is.readUnsignedShort(); + updateRectH = is.readUnsignedShort(); + updateRectEncoding = is.readInt(); + + if (updateRectEncoding == EncodingZlib || + updateRectEncoding == EncodingZRLE || + updateRectEncoding == EncodingTight) + wereZlibUpdates = true; + + // If the session is being recorded: + /*- + if (rec != null) { + if (numUpdatesInSession > 1) + rec.flush(); // Flush the output on each rectangle. + rec.writeShortBE(updateRectX); + rec.writeShortBE(updateRectY); + rec.writeShortBE(updateRectW); + rec.writeShortBE(updateRectH); + if (updateRectEncoding == EncodingZlib && !recordFromBeginning) { + // Here we cannot write Zlib-encoded rectangles because the + // decoder won't be able to reproduce zlib stream state. + if (!zlibWarningShown) { + System.out.println("Warning: Raw encoding will be used " + + "instead of Zlib in recorded session."); + zlibWarningShown = true; + } + rec.writeIntBE(EncodingRaw); + } else { + rec.writeIntBE(updateRectEncoding); + if (updateRectEncoding == EncodingTight && !recordFromBeginning && + !tightWarningShown) { + System.out.println("Warning: Re-compressing Tight-encoded " + + "updates for session recording."); + tightWarningShown = true; + } + } + } + */ + + if (updateRectEncoding != RfbProto.EncodingPointerPos && ( updateRectEncoding < 0 || updateRectEncoding > MaxNormalEncoding )) + return; + + if (updateRectX + updateRectW > framebufferWidth || + updateRectY + updateRectH > framebufferHeight) { + throw new Exception("Framebuffer update rectangle too large: " + + updateRectW + "x" + updateRectH + " at (" + + updateRectX + "," + updateRectY + ")"); + } + } + + // Read CopyRect source X and Y. + + int copyRectSrcX, copyRectSrcY; + + void readCopyRect() throws IOException { + copyRectSrcX = is.readUnsignedShort(); + copyRectSrcY = is.readUnsignedShort(); + + // If the session is being recorded: + /*- + if (rec != null) { + rec.writeShortBE(copyRectSrcX); + rec.writeShortBE(copyRectSrcY); + } + */ + } + + + // + // Read a ServerCutText message + // + + String readServerCutText() throws IOException { + byte[] pad = new byte[3]; + readFully(pad); + int len = is.readInt(); + byte[] text = new byte[len]; + readFully(text); + return new String(text); + } + + + // + // Read an integer in compact representation (1..3 bytes). + // Such format is used as a part of the Tight encoding. + // Also, this method records data if session recording is active and + // the viewer's recordFromBeginning variable is set to true. + // + + int readCompactLen() throws IOException { + int[] portion = new int[3]; + portion[0] = is.readUnsignedByte(); + int byteCount = 1; + int len = portion[0] & 0x7F; + if ((portion[0] & 0x80) != 0) { + portion[1] = is.readUnsignedByte(); + byteCount++; + len |= (portion[1] & 0x7F) << 7; + if ((portion[1] & 0x80) != 0) { + portion[2] = is.readUnsignedByte(); + byteCount++; + len |= (portion[2] & 0xFF) << 14; + } + } + /*- + if (rec != null && recordFromBeginning) + for (int i = 0; i < byteCount; i++) + rec.writeByte(portion[i]); + */ + return len; + } + + + // + // Write a FramebufferUpdateRequest message + // + + byte[] framebufferUpdateRequest = new byte[10]; + synchronized void writeFramebufferUpdateRequest(int x, int y, int w, int h, + boolean incremental) + throws IOException + { + framebufferUpdateRequest[0] = (byte) FramebufferUpdateRequest; + framebufferUpdateRequest[1] = (byte) (incremental ? 1 : 0); + framebufferUpdateRequest[2] = (byte) ((x >> 8) & 0xff); + framebufferUpdateRequest[3] = (byte) (x & 0xff); + framebufferUpdateRequest[4] = (byte) ((y >> 8) & 0xff); + framebufferUpdateRequest[5] = (byte) (y & 0xff); + framebufferUpdateRequest[6] = (byte) ((w >> 8) & 0xff); + framebufferUpdateRequest[7] = (byte) (w & 0xff); + framebufferUpdateRequest[8] = (byte) ((h >> 8) & 0xff); + framebufferUpdateRequest[9] = (byte) (h & 0xff); + + os.write(framebufferUpdateRequest); + } + + + // + // Write a SetPixelFormat message + // + + synchronized void writeSetPixelFormat(int bitsPerPixel, int depth, boolean bigEndian, + boolean trueColour, + int redMax, int greenMax, int blueMax, + int redShift, int greenShift, int blueShift, boolean fGreyScale) // sf@2005) + throws IOException + { + byte[] b = new byte[20]; + + b[0] = (byte) SetPixelFormat; + b[4] = (byte) bitsPerPixel; + b[5] = (byte) depth; + b[6] = (byte) (bigEndian ? 1 : 0); + b[7] = (byte) (trueColour ? 1 : 0); + b[8] = (byte) ((redMax >> 8) & 0xff); + b[9] = (byte) (redMax & 0xff); + b[10] = (byte) ((greenMax >> 8) & 0xff); + b[11] = (byte) (greenMax & 0xff); + b[12] = (byte) ((blueMax >> 8) & 0xff); + b[13] = (byte) (blueMax & 0xff); + b[14] = (byte) redShift; + b[15] = (byte) greenShift; + b[16] = (byte) blueShift; + b[17] = (byte) (fGreyScale ? 1 : 0); // sf@2005 + + os.write(b); + } + + + // + // Write a FixColourMapEntries message. The values in the red, green and + // blue arrays are from 0 to 65535. + // + + synchronized void writeFixColourMapEntries(int firstColour, int nColours, + int[] red, int[] green, int[] blue) + throws IOException + { + byte[] b = new byte[6 + nColours * 6]; + + b[0] = (byte) FixColourMapEntries; + b[2] = (byte) ((firstColour >> 8) & 0xff); + b[3] = (byte) (firstColour & 0xff); + b[4] = (byte) ((nColours >> 8) & 0xff); + b[5] = (byte) (nColours & 0xff); + + for (int i = 0; i < nColours; i++) { + b[6 + i * 6] = (byte) ((red[i] >> 8) & 0xff); + b[6 + i * 6 + 1] = (byte) (red[i] & 0xff); + b[6 + i * 6 + 2] = (byte) ((green[i] >> 8) & 0xff); + b[6 + i * 6 + 3] = (byte) (green[i] & 0xff); + b[6 + i * 6 + 4] = (byte) ((blue[i] >> 8) & 0xff); + b[6 + i * 6 + 5] = (byte) (blue[i] & 0xff); + } + + os.write(b); + } + + + // + // Write a SetEncodings message + // + + synchronized void writeSetEncodings(int[] encs, int len) throws IOException { + byte[] b = new byte[4 + 4 * len]; + + b[0] = (byte) SetEncodings; + b[2] = (byte) ((len >> 8) & 0xff); + b[3] = (byte) (len & 0xff); + + for (int i = 0; i < len; i++) { + b[4 + 4 * i] = (byte) ((encs[i] >> 24) & 0xff); + b[5 + 4 * i] = (byte) ((encs[i] >> 16) & 0xff); + b[6 + 4 * i] = (byte) ((encs[i] >> 8) & 0xff); + b[7 + 4 * i] = (byte) (encs[i] & 0xff); + } + + os.write(b); + } + + + // + // Write a ClientCutText message + // + + synchronized void writeClientCutText(String text) throws IOException { + byte[] b = new byte[8 + text.length()]; + + b[0] = (byte) ClientCutText; + b[4] = (byte) ((text.length() >> 24) & 0xff); + b[5] = (byte) ((text.length() >> 16) & 0xff); + b[6] = (byte) ((text.length() >> 8) & 0xff); + b[7] = (byte) (text.length() & 0xff); + + System.arraycopy(text.getBytes(), 0, b, 8, text.length()); + + os.write(b); + } + + + // + // A buffer for putting pointer and keyboard events before being sent. This + // is to ensure that multiple RFB events generated from a single Java Event + // will all be sent in a single network packet. The maximum possible + // length is 4 modifier down events, a single key event followed by 4 + // modifier up events i.e. 9 key events or 72 bytes. + // + + byte[] eventBuf = new byte[72]; + int eventBufLen; + + + /** + * Write a pointer event message. We may need to send modifier key events + * around it to set the correct modifier state. + * @param x + * @param y + * @param modifiers + * @param pointerMask + * @throws IOException + */ + synchronized void writePointerEvent( int x, int y, int modifiers, int pointerMask) throws IOException + { + eventBufLen = 0; + writeModifierKeyEvents(modifiers); + + eventBuf[eventBufLen++] = (byte) PointerEvent; + eventBuf[eventBufLen++] = (byte) pointerMask; + eventBuf[eventBufLen++] = (byte) ((x >> 8) & 0xff); + eventBuf[eventBufLen++] = (byte) (x & 0xff); + eventBuf[eventBufLen++] = (byte) ((y >> 8) & 0xff); + eventBuf[eventBufLen++] = (byte) (y & 0xff); + + // + // Always release all modifiers after an "up" event + // + + if (pointerMask == 0) { + writeModifierKeyEvents(0); + } + + os.write(eventBuf, 0, eventBufLen); + } + + void writeCtrlAltDel() throws IOException { + final int DELETE = 0xffff; + final int CTRLALT = VncCanvas.CTRL_MASK | VncCanvas.ALT_MASK; + try { + // Press + eventBufLen = 0; + writeModifierKeyEvents(CTRLALT); + writeKeyEvent(DELETE, true); + os.write(eventBuf, 0, eventBufLen); + + // Release + eventBufLen = 0; + writeModifierKeyEvents(CTRLALT); + writeKeyEvent(DELETE, false); + + // Reset VNC server modifiers state + writeModifierKeyEvents(0); + os.write(eventBuf, 0, eventBufLen); + } catch (IOException e) { + e.printStackTrace(); + } + } + + // + // Write a key event message. We may need to send modifier key events + // around it to set the correct modifier state. Also we need to translate + // from the Java key values to the X keysym values used by the RFB protocol. + // + public synchronized void writeKeyEvent(int keySym, int metaState, boolean down) throws IOException { +// Log.i("writeKeyEvent","key = " + keySym + " metastate = " + metaState + " down = " + down); + eventBufLen = 0; + if (down) + writeModifierKeyEvents(metaState); + if (keySym != 0) + writeKeyEvent(keySym, down); + + // Always release all modifiers after an "up" event + if (!down) + writeModifierKeyEvents(0); + + os.write(eventBuf, 0, eventBufLen); + } + + + + + // + // Add a raw key event with the given X keysym to eventBuf. + // + + private void writeKeyEvent(int keysym, boolean down) { + eventBuf[eventBufLen++] = (byte) KeyboardEvent; + eventBuf[eventBufLen++] = (byte) (down ? 1 : 0); + eventBuf[eventBufLen++] = (byte) 0; + eventBuf[eventBufLen++] = (byte) 0; + eventBuf[eventBufLen++] = (byte) ((keysym >> 24) & 0xff); + eventBuf[eventBufLen++] = (byte) ((keysym >> 16) & 0xff); + eventBuf[eventBufLen++] = (byte) ((keysym >> 8) & 0xff); + eventBuf[eventBufLen++] = (byte) (keysym & 0xff); + } + + + // + // Write key events to set the correct modifier state. + // + + int oldModifiers = 0; + + void writeModifierKeyEvents(int newModifiers) { + if ((newModifiers & VncCanvas.CTRL_MASK) != (oldModifiers & VncCanvas.CTRL_MASK)) + writeKeyEvent(0xffe3, (newModifiers & VncCanvas.CTRL_MASK) != 0); + + if ((newModifiers & VncCanvas.SHIFT_MASK) != (oldModifiers & VncCanvas.SHIFT_MASK)) + writeKeyEvent(0xffe1, (newModifiers & VncCanvas.SHIFT_MASK) != 0); + + if ((newModifiers & VncCanvas.META_MASK) != (oldModifiers & VncCanvas.META_MASK)) + writeKeyEvent(0xffe7, (newModifiers & VncCanvas.META_MASK) != 0); + + if ((newModifiers & VncCanvas.ALT_MASK) != (oldModifiers & VncCanvas.ALT_MASK)) + writeKeyEvent(0xffe9, (newModifiers & VncCanvas.ALT_MASK) != 0); + + oldModifiers = newModifiers; + } + // + // Compress and write the data into the recorded session file. This + // method assumes the recording is on (rec != null). + // + + + public void startTiming() { + timing = true; + + // Carry over up to 1s worth of previous rate for smoothing. + + if (timeWaitedIn100us > 10000) { + timedKbits = timedKbits * 10000 / timeWaitedIn100us; + timeWaitedIn100us = 10000; + } + } + + public void stopTiming() { + timing = false; + if (timeWaitedIn100us < timedKbits/2) + timeWaitedIn100us = timedKbits/2; // upper limit 20Mbit/s + } + + public long kbitsPerSecond() { + return timedKbits * 10000 / timeWaitedIn100us; + } + + public long timeWaited() { + return timeWaitedIn100us; + } + + public void readFully(byte b[]) throws IOException { + readFully(b, 0, b.length); + } + + public void readFully(byte b[], int off, int len) throws IOException { + long before = 0; + timing = false; // for test + + if (timing) + before = System.currentTimeMillis(); + + is.readFully(b, off, len); + + if (timing) { + long after = System.currentTimeMillis(); + long newTimeWaited = (after - before) * 10; + int newKbits = len * 8 / 1000; + + // limit rate to between 10kbit/s and 40Mbit/s + + if (newTimeWaited > newKbits*1000) newTimeWaited = newKbits*1000; + if (newTimeWaited < newKbits/4) newTimeWaited = newKbits/4; + + timeWaitedIn100us += newTimeWaited; + timedKbits += newKbits; + } + } + + synchronized void writeOpenChat() throws Exception { + os.write(TextChat); // byte type + os.write(0); // byte pad 1 + os.write(0); // byte pad 2 + os.write(0); // byte pad 2 + writeInt(CHAT_OPEN); // int message length + } + + synchronized void writeCloseChat() throws Exception { + os.write(TextChat); // byte type + os.write(0); // byte pad 1 + os.write(0); // byte pad 2 + os.write(0); // byte pad 2 + writeInt(CHAT_CLOSE); // int message length + } + + synchronized void writeFinishedChat() throws Exception { + os.write(TextChat); // byte type + os.write(0); // byte pad 1 + os.write(0); // byte pad 2 + os.write(0); // byte pad 2 + writeInt(CHAT_FINISHED); // int message length + } + + String readTextChatMsg() throws Exception { + byte[] pad = new byte[3]; + readFully(pad); + int len = is.readInt(); + if (len == CHAT_OPEN) { + // Remote user requests chat + ///viewer.openChat(); + // Respond to chat request + writeOpenChat(); + return null; + } else if (len == CHAT_CLOSE) { + // Remote user ends chat + ///viewer.closeChat(); + return null; + } else if (len == CHAT_FINISHED) { + // Remote user says chat finished. + // Not sure why I should care about this state. + return null; + } else { + // Remote user sends message!! + if (len > 0) { + byte[] msg = new byte[len]; + readFully(msg); + return new String(msg); + } + } + return null; + } + + public synchronized void writeChatMessage(String msg) throws Exception { + os.write(TextChat); // byte type + os.write(0); // byte pad 1 + os.write(0); // byte pad 2 + os.write(0); // byte pad 2 + byte [] bytes = msg.getBytes("8859_1"); + byte [] outgoing = bytes; + if (bytes.length > 4096) { + outgoing = new byte[4096]; + System.arraycopy(bytes, 0, outgoing, 0, 4096); + } + writeInt(outgoing.length); // int message length + os.write(outgoing); // message + } +} diff --git a/app/src/main/java/android/androidVNC/Utils.java b/app/src/main/java/android/androidVNC/Utils.java new file mode 100644 index 0000000..d18f5eb --- /dev/null +++ b/app/src/main/java/android/androidVNC/Utils.java @@ -0,0 +1,75 @@ +package android.androidVNC; + +import android.app.Activity; +import android.app.ActivityManager; +import android.app.AlertDialog; +import android.app.ActivityManager.MemoryInfo; +import android.content.Context; +import android.content.DialogInterface; +import android.content.DialogInterface.OnClickListener; +import android.content.Intent; +import android.net.Uri; +import android.text.Html; + +public class Utils { + + public static void showYesNoPrompt(Context _context, String title, String message, OnClickListener onYesListener, OnClickListener onNoListener) { + AlertDialog.Builder builder = new AlertDialog.Builder(_context); + builder.setTitle(title); + builder.setIcon(android.R.drawable.ic_dialog_info); // lame icon + builder.setMessage(message); + builder.setCancelable(false); + builder.setPositiveButton("Yes", onYesListener); + builder.setNegativeButton("No", onNoListener); + builder.show(); + } + + private static final Intent docIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://code.google.com/p/android-vnc-viewer/wiki/Documentation")); + + public static ActivityManager getActivityManager(Context context) + { + ActivityManager result = (ActivityManager)context.getSystemService(Context.ACTIVITY_SERVICE); + if (result == null) + throw new UnsupportedOperationException("Could not retrieve ActivityManager"); + return result; + } + + public static MemoryInfo getMemoryInfo(Context _context) { + MemoryInfo info = new MemoryInfo(); + getActivityManager(_context).getMemoryInfo(info); + return info; + } + + public static void showDocumentation(Context c) { + c.startActivity(docIntent); + } + + private static int nextNoticeID = 0; + public static int nextNoticeID() { + nextNoticeID++; + return nextNoticeID; + } + + public static void showErrorMessage(Context _context, String message) { + showMessage(_context, "Error!", message, android.R.drawable.ic_dialog_alert, null); + } + + public static void showFatalErrorMessage(final Context _context, String message) { + showMessage(_context, "Error!", message, android.R.drawable.ic_dialog_alert, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + ((Activity) _context).finish(); + } + }); + } + + public static void showMessage(Context _context, String title, String message, int icon, DialogInterface.OnClickListener ackHandler) { + AlertDialog.Builder builder = new AlertDialog.Builder(_context); + builder.setTitle(title); + builder.setMessage(Html.fromHtml(message)); + builder.setCancelable(false); + builder.setPositiveButton("Acknowledged", ackHandler); + builder.setIcon(icon); + builder.show(); + } +} diff --git a/app/src/main/java/android/androidVNC/VncCanvas.java b/app/src/main/java/android/androidVNC/VncCanvas.java new file mode 100644 index 0000000..eae0823 --- /dev/null +++ b/app/src/main/java/android/androidVNC/VncCanvas.java @@ -0,0 +1,2078 @@ +// +// Copyright (C) 2010 Michael A. MacDonald +// Copyright (C) 2004 Horizon Wimba. All Rights Reserved. +// Copyright (C) 2001-2003 HorizonLive.com, Inc. All Rights Reserved. +// Copyright (C) 2001,2002 Constantin Kaplinsky. All Rights Reserved. +// Copyright (C) 2000 Tridia Corporation. All Rights Reserved. +// Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. +// +// This is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This software is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this software; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. +// +// +// VncCanvas is a subclass of android.view.SurfaceView which draws a VNC +// desktop on it. +// +package android.androidVNC; + +import android.app.Activity; +import android.app.ProgressDialog; +import android.content.Context; +import android.content.DialogInterface; +import android.content.Intent; +import android.graphics.Color; +import android.graphics.Paint; +import android.graphics.Paint.Style; +import android.graphics.Point; +import android.graphics.Rect; +import android.os.Handler; +import android.util.AttributeSet; +import android.util.Log; +import android.view.Display; +import android.view.InputDevice; +import android.view.KeyEvent; +import android.view.MotionEvent; +import android.view.View; + +import com.antlersoft.android.bc.BCFactory; +import com.vectras.qemu.Config; +import com.vectras.vm.utils.UIUtils; + +import java.io.IOException; +import java.util.zip.Inflater; + +import androidx.appcompat.widget.AppCompatImageView; + +public class VncCanvas extends AppCompatImageView { + + private final static String TAG = "VncCanvas"; + private final static boolean LOCAL_LOGV = true; + public AbstractScaling scaling; + // Available to activity + public int mouseX, mouseY; + // Connection parameters + ConnectionBean connection; + // Runtime control flags + private boolean maintainConnection = true; + private boolean showDesktopInfo = true; + private boolean repaintsEnabled = true; + /** + * Use camera button as meta key for right mouse button + */ + boolean cameraButtonDown = false; + // Keep track when a seeming key press was the result of a menu shortcut + int lastKeyDown; + boolean afterMenu; + // Color Model settings + private COLORMODEL pendingColorModel = COLORMODEL.C24bit; + public COLORMODEL colorModel = null; + private int bytesPerPixel = 0; + private int[] colorPalette = null; + // VNC protocol connection + public RfbProto rfb; + // Internal bitmap data + AbstractBitmapData bitmapData; + public Handler handler = new Handler(); + // VNC Encoding parameters + private boolean useCopyRect = false; // TODO CopyRect is not working + private int preferredEncoding = -1; + // Unimplemented VNC encoding parameters + private boolean requestCursorUpdates = false; + private boolean ignoreCursorUpdates = true; + // Unimplemented TIGHT encoding parameters + private int compressLevel = -1; + private int jpegQuality = -1; + // Used to determine if encoding update is necessary + private int[] encodingsSaved = new int[20]; + private int nEncodingsSaved = 0; + // ZRLE encoder's data. + private byte[] zrleBuf; + private int[] zrleTilePixels; + private ZlibInStream zrleInStream; + // Zlib encoder's data. + private byte[] zlibBuf; + private Inflater zlibInflater; + private MouseScrollRunnable scrollRunnable; + private Paint handleRREPaint; + /** + * Position of the top left portion of the visible part of the + * screen, in full-frame coordinates + */ + int absoluteXPosition = 0, absoluteYPosition = 0; + public boolean mouseDown; + + /** + * Constructor used by the inflation apparatus + * + * @param context + */ + public VncCanvas(final Context context, AttributeSet attrs) { + super(context, attrs); + scrollRunnable = new MouseScrollRunnable(); + handleRREPaint = new Paint(); + handleRREPaint.setStyle(Style.FILL); + } + + public VncCanvas(Context context) { + super(context); + } + + public static int retries; + public static int MAX_RETRIES = 5; + + /** + * Create a view showing a VNC connection + * + * @param context + * Containing context (activity) + * @param bean + * Connection settings + * @param setModes + * Callback to run on UI thread after connection is set up + */ + void initializeVncCanvas(ConnectionBean bean, final Runnable setModes) { + connection = bean; + this.pendingColorModel = COLORMODEL.valueOf(bean.getColorModel()); + + setOnGenericMotionListener(new VNCGenericMotionListener_API12()); + setOnTouchListener(new VNCOnTouchListener()); + + // Startup the RFB thread with a nifty progess dialog + final ProgressDialog pd = ProgressDialog.show(getContext(), "Connecting to VM Console", "Please wait...", true, + true, new DialogInterface.OnCancelListener() { + @Override + public void onCancel(DialogInterface dialog) { + closeConnection(); + handler.post(new Runnable() { + public void run() { + Utils.showErrorMessage(getContext(), "VNC connection aborted!"); + } + }); + } + }); + final Display display = pd.getWindow().getWindowManager().getDefaultDisplay(); + Thread t = new Thread() { + + public void run() { + try { + int width = 0; + int height = 0; + Point size = new Point(); + display.getSize(size); + width = size.x; + height = size.y; + + connectAndAuthenticate(connection.getUserName(), connection.getPassword()); + doProtocolInitialisation(width, height); + handler.post(new Runnable() { + public void run() { + // pd.setMessage("Downloading first frame.\nPlease + // wait..."); + } + }); + processNormalProtocol(getContext(), pd, setModes); + } catch (Throwable e) { + if (maintainConnection) { + Log.e(TAG, e.toString()); + if(Config.debug) + e.printStackTrace(); + // Ensure we dismiss the progress dialog + // before we fatal error finish + if (pd.isShowing()) { + pd.dismiss(); + } + if (e instanceof OutOfMemoryError) { + // TODO Not sure if this will happen but... + // figure out how to gracefully notify the user + // Instantiating an alert dialog here doesn't work + // because we are out of memory. :( + } else if (e instanceof ArrayIndexOutOfBoundsException || e instanceof java.net.ConnectException + || e instanceof java.io.IOException) { + // Retry + if (retries < MAX_RETRIES) { + retries++; + reload(); + } + } else { + String error = "VNC connection failed!"; + if (e.getMessage() != null && (e.getMessage().indexOf("authentication") > -1)) { + error = "VNC authentication failed!"; + } + final String error_ = error + "
" + e.getLocalizedMessage(); + handler.post(new Runnable() { + public void run() { + Utils.showFatalErrorMessage(getContext(), error_); + } + }); + } + } + } + } + }; + t.start(); + } + + public void reload() { + Log.d(TAG, "Reconnecting..."); + Activity activity = ((Activity) getContext()); + Intent data = new Intent(); + activity.setResult(Config.VNC_RESET_RESULT_CODE, data); + activity.finish(); + + } + + void connectAndAuthenticate(String us, String pw) throws Exception { + Log.i(TAG, "Connecting to " + connection.getAddress() + ", port " + connection.getPort() + "..."); + + rfb = new RfbProto(connection.getAddress(), connection.getPort()); + if (LOCAL_LOGV) { + Log.v(TAG, "Connected to server"); + + } + + rfb.readVersionMsg(); + Log.i(TAG, "RFB server supports protocol version " + rfb.serverMajor + "." + rfb.serverMinor); + + rfb.writeVersionMsg(); + Log.i(TAG, "Using RFB protocol version " + rfb.clientMajor + "." + rfb.clientMinor); + + int bitPref = 0; + if (connection.getUserName().length() > 0) { + bitPref |= 1; + } + Log.d("debug", "bitPref=" + bitPref); + int secType = rfb.negotiateSecurity(bitPref); + int authType; + if (secType == RfbProto.SecTypeTight) { + rfb.initCapabilities(); + rfb.setupTunneling(); + authType = rfb.negotiateAuthenticationTight(); + } else if (secType == RfbProto.SecTypeUltra34) { + rfb.prepareDH(); + authType = RfbProto.AuthUltra; + } else { + authType = secType; + } + + switch (authType) { + case RfbProto.AuthNone: + Log.i(TAG, "No authentication needed"); + rfb.authenticateNone(); + break; + case RfbProto.AuthVNC: + Log.i(TAG, "VNC authentication needed"); + rfb.authenticateVNC(pw); + break; + case RfbProto.AuthUltra: + rfb.authenticateDH(us, pw); + break; + default: + throw new Exception("Unknown authentication scheme " + authType); + } + } + + void doProtocolInitialisation(int dx, int dy) throws IOException { + rfb.writeClientInit(); + rfb.readServerInit(); + + Log.i(TAG, "Desktop name is " + rfb.desktopName); + Log.i(TAG, "Desktop size is " + rfb.framebufferWidth + " x " + rfb.framebufferHeight); + + boolean useFull = false; + int capacity = BCFactory.getInstance().getBCActivityManager() + .getMemoryClass(Utils.getActivityManager(getContext())); + if (connection.getForceFull() == BitmapImplHint.AUTO) { + if (rfb.framebufferWidth * rfb.framebufferHeight * FullBufferBitmapData.CAPACITY_MULTIPLIER <= capacity + * 1024 * 1024) { + useFull = true; + } + } else { + useFull = (connection.getForceFull() == BitmapImplHint.FULL); + } + if (!useFull) { + bitmapData = new LargeBitmapData(rfb, this, dx, dy, capacity); + } else { + bitmapData = new FullBufferBitmapData(rfb, this, capacity); + } + mouseX = rfb.framebufferWidth / 2; + mouseY = rfb.framebufferHeight / 2; + + setPixelFormat(); + } + + private void setPixelFormat() throws IOException { + pendingColorModel.setPixelFormat(rfb); + bytesPerPixel = pendingColorModel.bpp(); + colorPalette = pendingColorModel.palette(); + colorModel = pendingColorModel; + pendingColorModel = null; + } + + public void setColorModel(COLORMODEL cm) { + // Only update if color model changes + if (colorModel == null || !colorModel.equals(cm)) { + pendingColorModel = cm; + } + } + + public boolean isColorModel(COLORMODEL cm) { + return (colorModel != null) && colorModel.equals(cm); + } + + private void mouseFollowPan() { + if (scaling.isAbleToPan()) { + int scrollx = absoluteXPosition; + int scrolly = absoluteYPosition; + int width = getVisibleWidth(); + int height = getVisibleHeight(); + // Log.i(TAG,"scrollx " + scrollx + " scrolly " + scrolly + + // " mouseX " + mouseX +" Y " + mouseY + " w " + width + " h " + + // height); + if (mouseX < scrollx || mouseX >= scrollx + width || mouseY < scrolly || mouseY >= scrolly + height) { + // Log.i(TAG,"warp to " + scrollx+width/2 + "," + scrolly + + // height/2); + warpMouse(scrollx + width / 2, scrolly + height / 2); + } + } + } + + public void processNormalProtocol(final Context context, ProgressDialog pd, final Runnable setModes) + throws Exception { + try { + bitmapData.writeFullUpdateRequest(false); + + handler.post(setModes); + connected(); + // + // main dispatch loop + // + while (maintainConnection) { + bitmapData.syncScroll(); + // Read message type from the server. + int msgType = rfb.readServerMessageType(); + bitmapData.doneWaiting(); + // Process the message depending on its type. + switch (msgType) { + case RfbProto.FramebufferUpdate: + rfb.readFramebufferUpdate(); + + for (int i = 0; i < rfb.updateNRects; i++) { + rfb.readFramebufferUpdateRectHdr(); + int rx = rfb.updateRectX, ry = rfb.updateRectY; + int rw = rfb.updateRectW, rh = rfb.updateRectH; + + if (rfb.updateRectEncoding == RfbProto.EncodingLastRect) { + Log.v(TAG, "rfb.EncodingLastRect"); + break; + } + + if (rfb.updateRectEncoding == RfbProto.EncodingNewFBSize) { + rfb.setFramebufferSize(rw, rh); + // - updateFramebufferSize(); + Log.v(TAG, "rfb.EncodingNewFBSize"); + reload(); + break; + } + + if (rfb.updateRectEncoding == RfbProto.EncodingXCursor + || rfb.updateRectEncoding == RfbProto.EncodingRichCursor) { + // - handleCursorShapeUpdate(rfb.updateRectEncoding, + // rx, + // ry, rw, rh); + Log.v(TAG, "rfb.EncodingCursor"); + continue; + + } + + if (rfb.updateRectEncoding == RfbProto.EncodingPointerPos) { + // This never actually happens + mouseX = rx; + mouseY = ry; + Log.v(TAG, "rfb.EncodingPointerPos"); + continue; + } + + rfb.startTiming(); + + switch (rfb.updateRectEncoding) { + case RfbProto.EncodingRaw: + handleRawRect(rx, ry, rw, rh); + break; + case RfbProto.EncodingCopyRect: + handleCopyRect(rx, ry, rw, rh); + Log.v(TAG, "CopyRect is Buggy!"); + break; + case RfbProto.EncodingRRE: + handleRRERect(rx, ry, rw, rh); + break; + case RfbProto.EncodingCoRRE: + handleCoRRERect(rx, ry, rw, rh); + break; + case RfbProto.EncodingHextile: + handleHextileRect(rx, ry, rw, rh); + break; + case RfbProto.EncodingZRLE: + handleZRLERect(rx, ry, rw, rh); + break; + case RfbProto.EncodingZlib: + handleZlibRect(rx, ry, rw, rh); + break; + default: + Log.e(TAG, "Unknown RFB rectangle encoding " + rfb.updateRectEncoding + " (0x" + + Integer.toHexString(rfb.updateRectEncoding) + ")"); + } + + rfb.stopTiming(); + + // Hide progress dialog + if (pd.isShowing()) { + pd.dismiss(); + } + } + + boolean fullUpdateNeeded = false; + + if (pendingColorModel != null) { + setPixelFormat(); + fullUpdateNeeded = true; + } + + setEncodings(true); + bitmapData.writeFullUpdateRequest(!fullUpdateNeeded); + + break; + + case RfbProto.SetColourMapEntries: + throw new Exception("Can't handle SetColourMapEntries message"); + + case RfbProto.Bell: + handler.post(new Runnable() { + public void run() { + UIUtils.toastShort(context, "VNC Beep"); + } + }); + break; + + case RfbProto.ServerCutText: + String s = rfb.readServerCutText(); + if (s != null && s.length() > 0) { + // TODO implement cut & paste + } + break; + + case RfbProto.TextChat: + // UltraVNC extension + String msg = rfb.readTextChatMsg(); + if (msg != null && msg.length() > 0) { + // TODO implement chat interface + } + break; + + default: + throw new Exception("Unknown RFB message type " + msgType); + } + } + } catch (Exception e) { + throw e; + } finally { + Log.v(TAG, "Closing VNC Connection"); + rfb.close(); + } + } + + /** + * Apply scroll offset and scaling to convert touch-space coordinates to the + * corresponding point on the full frame. + * + * @param e + * MotionEvent with the original, touch space coordinates. This + * event is altered in place. + * @return e -- The same event passed in, with the coordinates mapped + */ + MotionEvent changeTouchCoordinatesToFullFrame(MotionEvent e) { + // Log.v(TAG, String.format("tap at %f,%f", e.getX(), e.getY())); + float scale = getScale(); + + // Adjust coordinates for Android notification bar. + e.offsetLocation(0, -1f * getTop()); + + e.setLocation(absoluteXPosition + e.getX() / scale, absoluteYPosition + e.getY() / scale); + + return e; + } + + public void onDestroy() { + Log.v(TAG, "Cleaning up resources"); + if (bitmapData != null) { + bitmapData.dispose(); + } + bitmapData = null; + } + + /** + * Warp the mouse to x, y in the RFB coordinates + * + * @param x + * @param y + */ + void warpMouse(int x, int y) { + bitmapData.invalidateMousePosition(); + mouseX = x; + mouseY = y; + bitmapData.invalidateMousePosition(); + try { + rfb.writePointerEvent(x, y, 0, MOUSE_BUTTON_NONE); + } catch (IOException ioe) { + Log.w(TAG, ioe); + } + } + + /* + * f(x,s) is a function that returns the coordinate in screen/scroll space + * corresponding to the coordinate x in full-frame space with scaling s. + * + * This function returns the difference between f(x,s1) and f(x,s2) + * + * f(x,s) = (x - i/2) * s + ((i - w)/2)) * s = s (x - i/2 + i/2 + w/2) = s + * (x + w/2) + * + * + * f(x,s) = (x - ((i - w)/2)) * s + * + * @param oldscaling + * + * @param scaling + * + * @param imageDim + * + * @param windowDim + * + * @param offset + * + * @return + */ + /** + * Change to Canvas's scroll position to match the absoluteXPosition + */ + void scrollToAbsolute() { + float scale = getScale(); + try { + scrollTo((int) ((absoluteXPosition + ((float) getWidth() - getImageWidth()) / 2) * scale), + (int) ((absoluteYPosition + ((float) getHeight() - getImageHeight()) / 2) * scale)); + } catch (Exception e) { + Log.v("VNC", "Error: " + e.getMessage()); + } + } + + /** + * Make sure mouse is visible on displayable part of screen + */ + void panToMouse() { + if (!connection.getFollowMouse()) { + return; + } + + if (scaling != null && !scaling.isAbleToPan()) { + return; + } + + int x = mouseX; + int y = mouseY; + boolean panned = false; + int w = getVisibleWidth(); + int h = getVisibleHeight(); + int iw = getImageWidth(); + int ih = getImageHeight(); + + int newX = absoluteXPosition; + int newY = absoluteYPosition; + + if (x - newX >= w - 5) { + newX = x - w + 5; + if (newX + w > iw) { + newX = iw - w; + } + } else if (x < newX + 5) { + newX = x - 5; + if (newX < 0) { + newX = 0; + } + } + if (newX != absoluteXPosition) { + absoluteXPosition = newX; + panned = true; + } + if (y - newY >= h - 5) { + newY = y - h + 5; + if (newY + h > ih) { + newY = ih - h; + } + } else if (y < newY + 5) { + newY = y - 5; + if (newY < 0) { + newY = 0; + } + } + if (newY != absoluteYPosition) { + absoluteYPosition = newY; + panned = true; + } + if (panned) { + scrollToAbsolute(); + } + } + + /** + * Pan by a number of pixels (relative pan) + * + * @param dX + * @param dY + * @return True if the pan changed the view (did not move view out of + * bounds); false otherwise + */ + boolean pan(int dX, int dY) { + + double scale = getScale(); + + double sX = (double) dX / scale; + double sY = (double) dY / scale; + + if (absoluteXPosition + sX < 0) // dX = diff to 0 + { + sX = -absoluteXPosition; + } + if (absoluteYPosition + sY < 0) { + sY = -absoluteYPosition; + } + + // Prevent panning right or below desktop image + + Point outSize = new Point(); + int height = 0; + int width = 0; + VncCanvasActivity.display.getSize(outSize); + height = outSize.y; + width = outSize.x; + + if (absoluteXPosition + getVisibleWidth() + sX > getImageWidth()) { + sX = getImageWidth() - getVisibleWidth() - absoluteXPosition; + } + if (absoluteYPosition + getVisibleHeight() + sY > getImageHeight() + height * .6) { + sY = getImageHeight() + height * .6 - getVisibleHeight() - absoluteYPosition; + } + + absoluteXPosition += sX; + absoluteYPosition += sY; + if (sX != 0.0 || sY != 0.0) { + scrollToAbsolute(); + return true; + } + return false; + } + + /* + * (non-Javadoc) + * + * @see android.view.View#onScrollChanged(int, int, int, int) + */ + @Override + protected void onScrollChanged(int l, int t, int oldl, int oldt) { + super.onScrollChanged(l, t, oldl, oldt); + bitmapData.scrollChanged(absoluteXPosition, absoluteYPosition); + mouseFollowPan(); + } + + void handleRawRect(int x, int y, int w, int h) throws IOException { + handleRawRect(x, y, w, h, true); + } + + byte[] handleRawRectBuffer = new byte[128]; + + void handleRawRect(int x, int y, int w, int h, boolean paint) throws IOException { + boolean valid = bitmapData.validDraw(x, y, w, h); + int[] pixels = bitmapData.bitmapPixels; + if (bytesPerPixel == 1) { + // 1 byte per pixel. Use palette lookup table. + if (w > handleRawRectBuffer.length) { + handleRawRectBuffer = new byte[w]; + } + int i, offset; + for (int dy = y; dy < y + h; dy++) { + rfb.readFully(handleRawRectBuffer, 0, w); + if (!valid) { + continue; + } + offset = bitmapData.offset(x, dy); + for (i = 0; i < w; i++) { + pixels[offset + i] = colorPalette[0xFF & handleRawRectBuffer[i]]; + } + } + } else { + // 4 bytes per pixel (argb) 24-bit color + + final int l = w * 4; + if (l > handleRawRectBuffer.length) { + handleRawRectBuffer = new byte[l]; + } + int i, offset; + for (int dy = y; dy < y + h; dy++) { + rfb.readFully(handleRawRectBuffer, 0, l); + if (!valid) { + continue; + } + offset = bitmapData.offset(x, dy); + for (i = 0; i < w; i++) { + final int idx = i * 4; + pixels[offset + i] = // 0xFF << 24 | + (handleRawRectBuffer[idx + 2] & 0xff) << 16 | (handleRawRectBuffer[idx + 1] & 0xff) << 8 + | (handleRawRectBuffer[idx] & 0xff); + } + } + } + + if (!valid) { + return; + } + + bitmapData.updateBitmap(x, y, w, h); + + if (paint) { + reDraw(); + } + } + + private Runnable reDraw = new Runnable() { + public void run() { + if (showDesktopInfo) { + // Show a Toast with the desktop info on first frame draw. + showDesktopInfo = false; + showConnectionInfo(); + } + if (bitmapData != null) { + bitmapData.updateView(VncCanvas.this); + } + } + }; + + private void reDraw() { + if (repaintsEnabled) { + handler.post(reDraw); + } + } + + public void disableRepaints() { + repaintsEnabled = false; + } + + public void enableRepaints() { + repaintsEnabled = true; + } + + public void showConnectionInfo() { + String msg = rfb.desktopName; + int idx = rfb.desktopName.indexOf("("); + if (idx > -1) { + // Breakup actual desktop name from IP addresses for improved + // readability + String dn = rfb.desktopName.substring(0, idx).trim(); + String ip = rfb.desktopName.substring(idx).trim(); + msg = dn + "\n" + ip; + } + msg += "\n" + rfb.framebufferWidth + "x" + rfb.framebufferHeight; + String enc = getEncoding(); + // Encoding might not be set when we display this message + if (enc != null && !enc.equals("")) { + msg += ", " + getEncoding() + " encoding, " + colorModel.toString(); + } else { + msg += ", " + colorModel.toString(); + } + // Toast.makeText(getContext(), msg, Toast.LENGTH_LONG).show(); + } + + private String getEncoding() { + switch (preferredEncoding) { + case RfbProto.EncodingRaw: + return "RAW"; + case RfbProto.EncodingTight: + return "TIGHT"; + case RfbProto.EncodingCoRRE: + return "CoRRE"; + case RfbProto.EncodingHextile: + return "HEXTILE"; + case RfbProto.EncodingRRE: + return "RRE"; + case RfbProto.EncodingZlib: + return "ZLIB"; + case RfbProto.EncodingZRLE: + return "ZRLE"; + } + return ""; + } + + // Useful shortcuts for modifier masks. + final static int CTRL_MASK = KeyEvent.META_SYM_ON; + final static int SHIFT_MASK = KeyEvent.META_SHIFT_ON; + final static int META_MASK = 0; + final static int ALT_MASK = KeyEvent.META_ALT_ON; + private static final int MOUSE_BUTTON_NONE = 0; + static final int MOUSE_BUTTON_LEFT = 1; + static final int MOUSE_BUTTON_MIDDLE = 2; + static final int MOUSE_BUTTON_RIGHT = 4; + static final int MOUSE_BUTTON_SCROLL_UP = 8; + static final int MOUSE_BUTTON_SCROLL_DOWN = 16; + /** + * Current state of "mouse" buttons Alt meta means use second mouse button 0 + * = none 1 = default button 2 = second button + */ + private int pointerMask = MOUSE_BUTTON_NONE; + private boolean ALT_PRESSED = false; + private boolean CTRL_PRESSED = false; + + /** + * Convert a motion event to a format suitable for sending over the wire + * + * @param evt + * motion event; x and y must already have been converted from + * screen coordinates to remote frame buffer coordinates. + * cameraButton flag is interpreted as second mouse button + * @param downEvent + * True if "mouse button" (touch or trackball button) is down + * when this happens + * @return true if event was actually sent + */ + public boolean processPointerEvent(MotionEvent evt, boolean downEvent) { + return processPointerEvent(evt, downEvent, cameraButtonDown); + } + + /** + * Convert a motion event to a format suitable for sending over the wire + * + * @param evt + * motion event; x and y must already have been converted from + * screen coordinates to remote frame buffer coordinates. + * @param downEvent + * True if "mouse button" (touch or trackball button) is down + * when this happens + * @param useRightButton + * If true, event is interpreted as happening with right mouse + * button + * @return true if event was actually sent + */ + public boolean processPointerEvent(MotionEvent evt, boolean downEvent, boolean useRightButton) { + boolean useMiddleButton = false; + + if(evt.getButtonState() == MotionEvent.BUTTON_SECONDARY){ + useRightButton = true; + } else if(evt.getButtonState() == MotionEvent.BUTTON_TERTIARY){ + useMiddleButton = true; + } + + //XXX: not reliable with laptop trackpads +// if(Config.mouseMode == Config.MouseMode.External +// && MotionEvent.TOOL_TYPE_FINGER == evt.getToolType(0)) +// return true; +// +// if(Config.mouseMode == Config.MouseMode.Trackpad +// && MotionEvent.TOOL_TYPE_MOUSE == evt.getToolType(0)) +// return true; + + return processPointerEvent((int) evt.getX(), (int) evt.getY(), evt.getAction(), evt.getMetaState(), downEvent, + useRightButton, useMiddleButton, false); + } + + boolean processPointerEvent(int x, int y, int action, + int modifiers, boolean mouseIsDown, boolean useRightButton, + boolean useMiddleButton, boolean scrollUp) { + //Log.v("Limbo", "processPointerEvent: " + x + ", " + y + ", " + // + action + ", " + modifiers + ", " + mouseIsDown + ", " + // + useRightButton + ", " + useMiddleButton + ", " + scrollUp + //); + + if (rfb != null && rfb.inNormalProtocol) { + if (action == MotionEvent.ACTION_DOWN || (mouseIsDown && action == MotionEvent.ACTION_MOVE)) { + if (useRightButton) { + // Log.v("Limbo", "Right Button Down"); + pointerMask |= MOUSE_BUTTON_RIGHT; + } else if (useMiddleButton) { + pointerMask |= MOUSE_BUTTON_MIDDLE; + }else { + //Log.v("Limbo", "Left Button Down: x=" + x + ", y=" + y); + pointerMask |= MOUSE_BUTTON_LEFT; + } + } else if (action == MotionEvent.ACTION_SCROLL) { + // Log.v("Limbo", "Button Up"); + if(scrollUp) + pointerMask |= MOUSE_BUTTON_SCROLL_UP; + else + pointerMask |= MOUSE_BUTTON_SCROLL_DOWN; + } else if (action == MotionEvent.ACTION_UP) { + // Log.v("Limbo", "Button Up"); + //pointerMask = 0; + if (useRightButton) { + // Log.v("Limbo", "Right Button Down"); + pointerMask &= ~MOUSE_BUTTON_RIGHT; + } else if (useMiddleButton) { + pointerMask &= ~MOUSE_BUTTON_MIDDLE; + }else { + //Log.v("Limbo", "Left Button Down: x=" + x + ", y=" + y); + //XXX: Mouse middle click cannot always be detected so we + // reset all buttons (left, middle, click) to be safe + pointerMask = 0; + } + } + bitmapData.invalidateMousePosition(); + mouseX = x; + mouseY = y; + if (mouseX < 0) { + mouseX = 0; + } else if (mouseX >= rfb.framebufferWidth) { + mouseX = rfb.framebufferWidth - 1; + } + if (mouseY < 0) { + mouseY = 0; + } else if (mouseY >= rfb.framebufferHeight) { + mouseY = rfb.framebufferHeight - 1; + } + bitmapData.invalidateMousePosition(); + try { + rfb.writePointerEvent(mouseX, mouseY, modifiers, pointerMask); + if (action == MotionEvent.ACTION_SCROLL) { + rfb.writePointerEvent(mouseX, mouseY, 0, 0); + pointerMask = 0; + } + } catch (Exception e) { + e.printStackTrace(); + } + panToMouse(); + return true; + } + + return false; + } + + private int isSpecialKey(int key) { + switch (key) { + case '!': + return '1'; + case '@': + return '2'; + case '#': + return '3'; + case '$': + return '4'; + case '%': + return '5'; + case '^': + return '6'; + case '&': + return '7'; + case '*': + return '8'; + case '(': + return '9'; + case ')': + return '0'; + case '_': + return '-'; + case '+': + return '='; + case '~': + return '`'; + case '{': + return '['; + case '}': + return ']'; + case '|': + return '\\'; + case '\"': + return '\''; + case ':': + return ';'; + case '<': + return ','; + case '>': + return '.'; + case '?': + return '/'; + default: + return -1; + + } } + + /** + * Moves the scroll while the volume key is held down + * + * @author Michael A. MacDonald + */ + class MouseScrollRunnable implements Runnable { + + int delay = 100; + int scrollButton = 0; + + /* + * (non-Javadoc) + * + * @see java.lang.Runnable#run() + */ + @Override + public void run() { + try { + rfb.writePointerEvent(mouseX, mouseY, 0, scrollButton); + rfb.writePointerEvent(mouseX, mouseY, 0, 0); + + handler.postDelayed(this, delay); + } catch (IOException ioe) { + } + } + } + + public synchronized boolean processLocalKeyEvent(int keyCode, KeyEvent evt) { + if (keyCode == KeyEvent.KEYCODE_MENU) // Ignore menu key + { + return true; + } + if (keyCode == KeyEvent.KEYCODE_CAMERA) { + cameraButtonDown = (evt.getAction() != KeyEvent.ACTION_UP); + } else if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN || keyCode == KeyEvent.KEYCODE_VOLUME_UP) { + int mouseChange = keyCode == KeyEvent.KEYCODE_VOLUME_DOWN ? MOUSE_BUTTON_SCROLL_DOWN + : MOUSE_BUTTON_SCROLL_UP; + if (evt.getAction() == KeyEvent.ACTION_DOWN) { + // If not auto-repeat + if (scrollRunnable.scrollButton != mouseChange) { + pointerMask |= mouseChange; + scrollRunnable.scrollButton = mouseChange; + handler.postDelayed(scrollRunnable, 200); + } + } else { + handler.removeCallbacks(scrollRunnable); + scrollRunnable.scrollButton = 0; + pointerMask &= ~mouseChange; + } + try { + rfb.writePointerEvent(mouseX, mouseY, evt.getMetaState(), pointerMask); + } catch (IOException ioe) { + // TODO: do something with exception + } + return true; + } + if (rfb != null && rfb.inNormalProtocol) { + boolean down = (evt.getAction() == KeyEvent.ACTION_DOWN); + int key; + int metaState = evt.getMetaState(); + metaState = 0; + // Log.v("Key Pressed", keyCode + ", metaState = " + metaState); + + switch (keyCode) { + case KeyEvent.KEYCODE_BACK: + // key = 0xff1b; + return false; + // break; + case KeyEvent.KEYCODE_DPAD_LEFT: + key = 0xff51; + break; + case KeyEvent.KEYCODE_DPAD_UP: + key = 0xff52; + break; + case KeyEvent.KEYCODE_DPAD_RIGHT: + key = 0xff53; + break; + case KeyEvent.KEYCODE_DPAD_DOWN: + key = 0xff54; + break; + case KeyEvent.KEYCODE_DEL: + key = 0xff08; + break; + case KeyEvent.KEYCODE_FORWARD_DEL: + key = MetaKeyBean.keysByKeyCode.get(KeyEvent.KEYCODE_DEL).keySym; + break; + case KeyEvent.KEYCODE_ALT_LEFT: + case KeyEvent.KEYCODE_ALT_RIGHT: + this.ALT_PRESSED = true; + return true; + case KeyEvent.KEYCODE_MOVE_HOME: + key = 0xFF50; + break; + case KeyEvent.KEYCODE_INSERT: + key = 0xFF63; + break; + case KeyEvent.KEYCODE_MOVE_END: + key = 0xFF57; + break; + case KeyEvent.KEYCODE_PAGE_DOWN: + key = 0xFF56; + break; + case KeyEvent.KEYCODE_PAGE_UP: + key = 0xFF55; + break; + case KeyEvent.KEYCODE_ENTER: + key = 0xff0d; + break; + case KeyEvent.KEYCODE_DPAD_CENTER: + key = 0xff0d; + break; + case KeyEvent.KEYCODE_TAB: + key = 0xFF09; + break; + case 111: // ESCAPE + key = 0xff1b; + break; + default: + key = evt.getUnicodeChar(); + //Log.v("unicode", "Unicode Char for " + evt.getKeyCode() + " is " + key); + + //ΧΧΧ: Workaround for some chars not recognized by QEMU + int specialKey = isSpecialKey(key); + if (specialKey != -1) { + key = specialKey; + metaState = metaState | VncCanvas.SHIFT_MASK; + } else if (keyCode >= 131 && keyCode <= 142) { + // Function Key pressed + key = 0xFFBE + keyCode - 131; + } else if (key == 0){ + //Key is a meta combination or unknown + key = evt.getUnicodeChar(0); + } + + break; + } + + if ((evt.getMetaState() & KeyEvent.META_CTRL_ON) == KeyEvent.META_CTRL_ON) { + // Log.v("meta", "setting ctrl mask"); + metaState = metaState | VncCanvas.CTRL_MASK; + } + + if ((evt.getMetaState() & KeyEvent.META_ALT_ON) == KeyEvent.META_ALT_ON || this.ALT_PRESSED) { + // Log.v("meta", "setting alt mask"); + metaState = metaState | VncCanvas.ALT_MASK; + } + + if ((evt.getMetaState() & KeyEvent.META_SHIFT_ON) == KeyEvent.META_SHIFT_ON) { + // Log.v("meta", "setting shift mask"); + metaState = metaState | VncCanvas.SHIFT_MASK; + } + try { + if (afterMenu) { + afterMenu = false; + if (!down && key != lastKeyDown) { + return true; + } + } + if (down) { + lastKeyDown = key; + } + + rfb.writeKeyEvent(key, metaState, down); + this.ALT_PRESSED = false; + } catch (Exception e) { + e.printStackTrace(); + } + return true; + } + return false; + } + + public void closeConnection() { + maintainConnection = false; + } + + public void sendMetaKey1(int key, int flags) { + try { + rfb.writeKeyEvent(key, flags, true); + rfb.writeKeyEvent(key, flags, false); + } catch (IOException ioe) { + ioe.printStackTrace(); + } + + } + + public void sendText(String s) { + int l = s.length(); + for (int i = 0; i < l; i++) { + char c = s.charAt(i); + int meta = 0; + int keysym = c; + if (Character.isISOControl(c)) { + if (c == '\n') { + keysym = MetaKeyBean.keysByKeyCode.get(KeyEvent.KEYCODE_ENTER).keySym; + } else { + continue; + } + } + try { + rfb.writeKeyEvent(keysym, meta, true); + rfb.writeKeyEvent(keysym, meta, false); + } catch (IOException ioe) { + // TODO: log this + } + } + } + + void sendMetaKey(MetaKeyBean meta) { + if (meta.isMouseClick()) { + try { + rfb.writePointerEvent(mouseX, mouseY, meta.getMetaFlags(), meta.getMouseButtons()); + rfb.writePointerEvent(mouseX, mouseY, meta.getMetaFlags(), 0); + } catch (IOException ioe) { + ioe.printStackTrace(); + } + } else { + try { + rfb.writeKeyEvent(meta.getKeySym(), meta.getMetaFlags(), true); + rfb.writeKeyEvent(meta.getKeySym(), meta.getMetaFlags(), false); + } catch (IOException ioe) { + ioe.printStackTrace(); + } + } + } + + float getScale() { + if (scaling == null) { + return 1; + } + return scaling.getScale(); + } + + public int getVisibleWidth() { + return (int) ((double) getWidth() / getScale() + 0.5); + } + + public int getVisibleHeight() { + return (int) ((double) getHeight() / getScale() + 0.5); + } + + public int getImageWidth() { + return bitmapData.framebufferwidth; + } + + public int getImageHeight() { + return bitmapData.framebufferheight; + } + + public int getCenteredXOffset() { + int xoffset = (bitmapData.framebufferwidth - getWidth()) / 2; + return xoffset; + } + + public int getCenteredYOffset() { + int yoffset = (bitmapData.framebufferheight - getHeight()) / 2; + return yoffset; + } + + /** + * Additional Encodings + * + */ + private void setEncodings(boolean autoSelectOnly) { + if (rfb == null || !rfb.inNormalProtocol) { + return; + } + + if (preferredEncoding == -1) { + // Preferred format is ZRLE + preferredEncoding = RfbProto.EncodingZRLE; + } else { + // Auto encoder selection is not enabled. + if (autoSelectOnly) { + return; + } + } + + int[] encodings = new int[20]; + int nEncodings = 0; + + encodings[nEncodings++] = preferredEncoding; + if (useCopyRect) { + encodings[nEncodings++] = RfbProto.EncodingCopyRect; + } + // if (preferredEncoding != RfbProto.EncodingTight) + // encodings[nEncodings++] = RfbProto.EncodingTight; + if (preferredEncoding != RfbProto.EncodingZRLE) { + encodings[nEncodings++] = RfbProto.EncodingZRLE; + } + if (preferredEncoding != RfbProto.EncodingHextile) { + encodings[nEncodings++] = RfbProto.EncodingHextile; + } + if (preferredEncoding != RfbProto.EncodingZlib) { + encodings[nEncodings++] = RfbProto.EncodingZlib; + } + if (preferredEncoding != RfbProto.EncodingCoRRE) { + encodings[nEncodings++] = RfbProto.EncodingCoRRE; + } + if (preferredEncoding != RfbProto.EncodingRRE) { + encodings[nEncodings++] = RfbProto.EncodingRRE; + } + + if (compressLevel >= 0 && compressLevel <= 9) { + encodings[nEncodings++] = RfbProto.EncodingCompressLevel0 + compressLevel; + } + if (jpegQuality >= 0 && jpegQuality <= 9) { + encodings[nEncodings++] = RfbProto.EncodingQualityLevel0 + jpegQuality; + } + + if (requestCursorUpdates) { + encodings[nEncodings++] = RfbProto.EncodingXCursor; + encodings[nEncodings++] = RfbProto.EncodingRichCursor; + if (!ignoreCursorUpdates) { + encodings[nEncodings++] = RfbProto.EncodingPointerPos; + } + } + + encodings[nEncodings++] = RfbProto.EncodingLastRect; + encodings[nEncodings++] = RfbProto.EncodingNewFBSize; + + boolean encodingsWereChanged = false; + if (nEncodings != nEncodingsSaved) { + encodingsWereChanged = true; + } else { + for (int i = 0; i < nEncodings; i++) { + if (encodings[i] != encodingsSaved[i]) { + encodingsWereChanged = true; + break; + } + } + } + + if (encodingsWereChanged) { + try { + rfb.writeSetEncodings(encodings, nEncodings); + } catch (Exception e) { + e.printStackTrace(); + } + encodingsSaved = encodings; + nEncodingsSaved = nEncodings; + } + } + + // + // Handle a CopyRect rectangle. + // + final Paint handleCopyRectPaint = new Paint(); + + private void handleCopyRect(int x, int y, int w, int h) throws IOException { + + /** + * This does not work properly yet. + */ + rfb.readCopyRect(); + if (!bitmapData.validDraw(x, y, w, h)) { + return; + } + // Source Coordinates + int leftSrc = rfb.copyRectSrcX; + int topSrc = rfb.copyRectSrcY; + int rightSrc = topSrc + w; + int bottomSrc = topSrc + h; + + // Change + int dx = x - rfb.copyRectSrcX; + int dy = y - rfb.copyRectSrcY; + + // Destination Coordinates + int leftDest = leftSrc + dx; + int topDest = topSrc + dy; + int rightDest = rightSrc + dx; + int bottomDest = bottomSrc + dy; + + bitmapData.copyRect(new Rect(leftSrc, topSrc, rightSrc, bottomSrc), + new Rect(leftDest, topDest, rightDest, bottomDest), handleCopyRectPaint); + + reDraw(); + } + + byte[] bg_buf = new byte[4]; + byte[] rre_buf = new byte[128]; + + // + // Handle an RRE-encoded rectangle. + // + + private void handleRRERect(int x, int y, int w, int h) throws IOException { + boolean valid = bitmapData.validDraw(x, y, w, h); + int nSubrects = rfb.is.readInt(); + + rfb.readFully(bg_buf, 0, bytesPerPixel); + int pixel; + if (bytesPerPixel == 1) { + pixel = colorPalette[0xFF & bg_buf[0]]; + } else { + pixel = Color.rgb(bg_buf[2] & 0xFF, bg_buf[1] & 0xFF, bg_buf[0] & 0xFF); + } + handleRREPaint.setColor(pixel); + if (valid) { + bitmapData.drawRect(x, y, w, h, handleRREPaint); + } + + int len = nSubrects * (bytesPerPixel + 8); + if (len > rre_buf.length) { + rre_buf = new byte[len]; + } + + rfb.readFully(rre_buf, 0, len); + if (!valid) { + return; + } + + int sx, sy, sw, sh; + + int i = 0; + for (int j = 0; j < nSubrects; j++) { + if (bytesPerPixel == 1) { + pixel = colorPalette[0xFF & rre_buf[i++]]; + } else { + pixel = Color.rgb(rre_buf[i + 2] & 0xFF, rre_buf[i + 1] & 0xFF, rre_buf[i] & 0xFF); + i += 4; + } + sx = x + ((rre_buf[i] & 0xff) << 8) + (rre_buf[i + 1] & 0xff); + i += 2; + sy = y + ((rre_buf[i] & 0xff) << 8) + (rre_buf[i + 1] & 0xff); + i += 2; + sw = ((rre_buf[i] & 0xff) << 8) + (rre_buf[i + 1] & 0xff); + i += 2; + sh = ((rre_buf[i] & 0xff) << 8) + (rre_buf[i + 1] & 0xff); + i += 2; + + handleRREPaint.setColor(pixel); + bitmapData.drawRect(sx, sy, sw, sh, handleRREPaint); + } + + reDraw(); + } + + // + // Handle a CoRRE-encoded rectangle. + // + private void handleCoRRERect(int x, int y, int w, int h) throws IOException { + boolean valid = bitmapData.validDraw(x, y, w, h); + int nSubrects = rfb.is.readInt(); + + rfb.readFully(bg_buf, 0, bytesPerPixel); + int pixel; + if (bytesPerPixel == 1) { + pixel = colorPalette[0xFF & bg_buf[0]]; + } else { + pixel = Color.rgb(bg_buf[2] & 0xFF, bg_buf[1] & 0xFF, bg_buf[0] & 0xFF); + } + handleRREPaint.setColor(pixel); + if (valid) { + bitmapData.drawRect(x, y, w, h, handleRREPaint); + } + + int len = nSubrects * (bytesPerPixel + 8); + if (len > rre_buf.length) { + rre_buf = new byte[len]; + } + + rfb.readFully(rre_buf, 0, len); + if (!valid) { + return; + } + + int sx, sy, sw, sh; + int i = 0; + + for (int j = 0; j < nSubrects; j++) { + if (bytesPerPixel == 1) { + pixel = colorPalette[0xFF & rre_buf[i++]]; + } else { + pixel = Color.rgb(rre_buf[i + 2] & 0xFF, rre_buf[i + 1] & 0xFF, rre_buf[i] & 0xFF); + i += 4; + } + sx = x + (rre_buf[i++] & 0xFF); + sy = y + (rre_buf[i++] & 0xFF); + sw = rre_buf[i++] & 0xFF; + sh = rre_buf[i++] & 0xFF; + + handleRREPaint.setColor(pixel); + bitmapData.drawRect(sx, sy, sw, sh, handleRREPaint); + } + + reDraw(); + } + + // + // Handle a Hextile-encoded rectangle. + // + // These colors should be kept between handleHextileSubrect() calls. + private int hextile_bg, hextile_fg; + + private void handleHextileRect(int x, int y, int w, int h) throws IOException { + + hextile_bg = Color.BLACK; + hextile_fg = Color.BLACK; + + for (int ty = y; ty < y + h; ty += 16) { + int th = 16; + if (y + h - ty < 16) { + th = y + h - ty; + } + + for (int tx = x; tx < x + w; tx += 16) { + int tw = 16; + if (x + w - tx < 16) { + tw = x + w - tx; + } + + handleHextileSubrect(tx, ty, tw, th); + } + + // Finished with a row of tiles, now let's show it. + reDraw(); + } + } + + // + // Handle one tile in the Hextile-encoded data. + // + Paint handleHextileSubrectPaint = new Paint(); + byte[] backgroundColorBuffer = new byte[4]; + + private void handleHextileSubrect(int tx, int ty, int tw, int th) throws IOException { + + int subencoding = rfb.is.readUnsignedByte(); + + // Is it a raw-encoded sub-rectangle? + if ((subencoding & RfbProto.HextileRaw) != 0) { + handleRawRect(tx, ty, tw, th, false); + return; + } + + boolean valid = bitmapData.validDraw(tx, ty, tw, th); + // Read and draw the background if specified. + if (bytesPerPixel > backgroundColorBuffer.length) { + throw new RuntimeException("impossible colordepth"); + } + if ((subencoding & RfbProto.HextileBackgroundSpecified) != 0) { + rfb.readFully(backgroundColorBuffer, 0, bytesPerPixel); + if (bytesPerPixel == 1) { + hextile_bg = colorPalette[0xFF & backgroundColorBuffer[0]]; + } else { + hextile_bg = Color.rgb(backgroundColorBuffer[2] & 0xFF, backgroundColorBuffer[1] & 0xFF, + backgroundColorBuffer[0] & 0xFF); + } + } + handleHextileSubrectPaint.setColor(hextile_bg); + handleHextileSubrectPaint.setStyle(Paint.Style.FILL); + if (valid) { + bitmapData.drawRect(tx, ty, tw, th, handleHextileSubrectPaint); + } + + // Read the foreground color if specified. + if ((subencoding & RfbProto.HextileForegroundSpecified) != 0) { + rfb.readFully(backgroundColorBuffer, 0, bytesPerPixel); + if (bytesPerPixel == 1) { + hextile_fg = colorPalette[0xFF & backgroundColorBuffer[0]]; + } else { + hextile_fg = Color.rgb(backgroundColorBuffer[2] & 0xFF, backgroundColorBuffer[1] & 0xFF, + backgroundColorBuffer[0] & 0xFF); + } + } + + // Done with this tile if there is no sub-rectangles. + if ((subencoding & RfbProto.HextileAnySubrects) == 0) { + return; + } + + int nSubrects = rfb.is.readUnsignedByte(); + int bufsize = nSubrects * 2; + if ((subencoding & RfbProto.HextileSubrectsColoured) != 0) { + bufsize += nSubrects * bytesPerPixel; + } + if (rre_buf.length < bufsize) { + rre_buf = new byte[bufsize]; + } + rfb.readFully(rre_buf, 0, bufsize); + + int b1, b2, sx, sy, sw, sh; + int i = 0; + if ((subencoding & RfbProto.HextileSubrectsColoured) == 0) { + + // Sub-rectangles are all of the same color. + handleHextileSubrectPaint.setColor(hextile_fg); + for (int j = 0; j < nSubrects; j++) { + b1 = rre_buf[i++] & 0xFF; + b2 = rre_buf[i++] & 0xFF; + sx = tx + (b1 >> 4); + sy = ty + (b1 & 0xf); + sw = (b2 >> 4) + 1; + sh = (b2 & 0xf) + 1; + if (valid) { + bitmapData.drawRect(sx, sy, sw, sh, handleHextileSubrectPaint); + } + } + } else if (bytesPerPixel == 1) { + + // BGR233 (8-bit color) version for colored sub-rectangles. + for (int j = 0; j < nSubrects; j++) { + hextile_fg = colorPalette[0xFF & rre_buf[i++]]; + b1 = rre_buf[i++] & 0xFF; + b2 = rre_buf[i++] & 0xFF; + sx = tx + (b1 >> 4); + sy = ty + (b1 & 0xf); + sw = (b2 >> 4) + 1; + sh = (b2 & 0xf) + 1; + handleHextileSubrectPaint.setColor(hextile_fg); + if (valid) { + bitmapData.drawRect(sx, sy, sw, sh, handleHextileSubrectPaint); + } + } + + } else { + + // Full-color (24-bit) version for colored sub-rectangles. + for (int j = 0; j < nSubrects; j++) { + hextile_fg = Color.rgb(rre_buf[i + 2] & 0xFF, rre_buf[i + 1] & 0xFF, rre_buf[i] & 0xFF); + i += 4; + b1 = rre_buf[i++] & 0xFF; + b2 = rre_buf[i++] & 0xFF; + sx = tx + (b1 >> 4); + sy = ty + (b1 & 0xf); + sw = (b2 >> 4) + 1; + sh = (b2 & 0xf) + 1; + handleHextileSubrectPaint.setColor(hextile_fg); + if (valid) { + bitmapData.drawRect(sx, sy, sw, sh, handleHextileSubrectPaint); + } + } + + } + } + + // + // Handle a ZRLE-encoded rectangle. + // + Paint handleZRLERectPaint = new Paint(); + int[] handleZRLERectPalette = new int[128]; + + private void handleZRLERect(int x, int y, int w, int h) throws Exception { + + if (zrleInStream == null) { + zrleInStream = new ZlibInStream(); + } + + int nBytes = rfb.is.readInt(); + if (nBytes > 64 * 1024 * 1024) { + throw new Exception("ZRLE decoder: illegal compressed data size"); + } + + if (zrleBuf == null || zrleBuf.length < nBytes) { + zrleBuf = new byte[nBytes + 4096]; + } + + rfb.readFully(zrleBuf, 0, nBytes); + + zrleInStream.setUnderlying(new MemInStream(zrleBuf, 0, nBytes), nBytes); + + boolean valid = bitmapData.validDraw(x, y, w, h); + + for (int ty = y; ty < y + h; ty += 64) { + + int th = Math.min(y + h - ty, 64); + + for (int tx = x; tx < x + w; tx += 64) { + + int tw = Math.min(x + w - tx, 64); + + int mode = zrleInStream.readU8(); + boolean rle = (mode & 128) != 0; + int palSize = mode & 127; + + readZrlePalette(handleZRLERectPalette, palSize); + + if (palSize == 1) { + int pix = handleZRLERectPalette[0]; + int c = (bytesPerPixel == 1) ? colorPalette[0xFF & pix] : (0xFF000000 | pix); + handleZRLERectPaint.setColor(c); + handleZRLERectPaint.setStyle(Paint.Style.FILL); + if (valid) { + bitmapData.drawRect(tx, ty, tw, th, handleZRLERectPaint); + } + continue; + } + + if (!rle) { + if (palSize == 0) { + readZrleRawPixels(tw, th); + } else { + readZrlePackedPixels(tw, th, handleZRLERectPalette, palSize); + } + } else { + if (palSize == 0) { + readZrlePlainRLEPixels(tw, th); + } else { + readZrlePackedRLEPixels(tw, th, handleZRLERectPalette); + } + } + if (valid) { + handleUpdatedZrleTile(tx, ty, tw, th); + } + } + } + + zrleInStream.reset(); + + reDraw(); + } + + // + // Handle a Zlib-encoded rectangle. + // + byte[] handleZlibRectBuffer = new byte[128]; + + private void handleZlibRect(int x, int y, int w, int h) throws Exception { + boolean valid = bitmapData.validDraw(x, y, w, h); + int nBytes = rfb.is.readInt(); + + if (zlibBuf == null || zlibBuf.length < nBytes) { + zlibBuf = new byte[nBytes * 2]; + } + + rfb.readFully(zlibBuf, 0, nBytes); + + if (zlibInflater == null) { + zlibInflater = new Inflater(); + } + zlibInflater.setInput(zlibBuf, 0, nBytes); + + int[] pixels = bitmapData.bitmapPixels; + + if (bytesPerPixel == 1) { + // 1 byte per pixel. Use palette lookup table. + if (w > handleZlibRectBuffer.length) { + handleZlibRectBuffer = new byte[w]; + } + int i, offset; + for (int dy = y; dy < y + h; dy++) { + zlibInflater.inflate(handleZlibRectBuffer, 0, w); + if (!valid) { + continue; + } + offset = bitmapData.offset(x, dy); + for (i = 0; i < w; i++) { + pixels[offset + i] = colorPalette[0xFF & handleZlibRectBuffer[i]]; + } + } + } else { + // 24-bit color (ARGB) 4 bytes per pixel. + final int l = w * 4; + if (l > handleZlibRectBuffer.length) { + handleZlibRectBuffer = new byte[l]; + } + int i, offset; + for (int dy = y; dy < y + h; dy++) { + zlibInflater.inflate(handleZlibRectBuffer, 0, l); + if (!valid) { + continue; + } + offset = bitmapData.offset(x, dy); + for (i = 0; i < w; i++) { + final int idx = i * 4; + pixels[offset + i] = (handleZlibRectBuffer[idx + 2] & 0xFF) << 16 + | (handleZlibRectBuffer[idx + 1] & 0xFF) << 8 | (handleZlibRectBuffer[idx] & 0xFF); + } + } + } + if (!valid) { + return; + } + bitmapData.updateBitmap(x, y, w, h); + + reDraw(); + } + + private int readPixel(InStream is) throws Exception { + int pix; + if (bytesPerPixel == 1) { + pix = is.readU8(); + } else { + int p1 = is.readU8(); + int p2 = is.readU8(); + int p3 = is.readU8(); + pix = (p3 & 0xFF) << 16 | (p2 & 0xFF) << 8 | (p1 & 0xFF); + } + return pix; + } + + byte[] readPixelsBuffer = new byte[128]; + + private void readPixels(InStream is, int[] dst, int count) throws Exception { + if (bytesPerPixel == 1) { + if (count > readPixelsBuffer.length) { + readPixelsBuffer = new byte[count]; + } + is.readBytes(readPixelsBuffer, 0, count); + for (int i = 0; i < count; i++) { + dst[i] = (int) readPixelsBuffer[i] & 0xFF; + } + } else { + final int l = count * 3; + if (l > readPixelsBuffer.length) { + readPixelsBuffer = new byte[l]; + } + is.readBytes(readPixelsBuffer, 0, l); + for (int i = 0; i < count; i++) { + final int idx = i * 3; + dst[i] = ((readPixelsBuffer[idx + 2] & 0xFF) << 16 | (readPixelsBuffer[idx + 1] & 0xFF) << 8 + | (readPixelsBuffer[idx] & 0xFF)); + } + } + } + + private void readZrlePalette(int[] palette, int palSize) throws Exception { + readPixels(zrleInStream, palette, palSize); + } + + private void readZrleRawPixels(int tw, int th) throws Exception { + int len = tw * th; + if (zrleTilePixels == null || len > zrleTilePixels.length) { + zrleTilePixels = new int[len]; + } + readPixels(zrleInStream, zrleTilePixels, tw * th); // / + } + + private void readZrlePackedPixels(int tw, int th, int[] palette, int palSize) throws Exception { + + int bppp = ((palSize > 16) ? 8 : ((palSize > 4) ? 4 : ((palSize > 2) ? 2 : 1))); + int ptr = 0; + int len = tw * th; + if (zrleTilePixels == null || len > zrleTilePixels.length) { + zrleTilePixels = new int[len]; + } + + for (int i = 0; i < th; i++) { + int eol = ptr + tw; + int b = 0; + int nbits = 0; + + while (ptr < eol) { + if (nbits == 0) { + b = zrleInStream.readU8(); + nbits = 8; + } + nbits -= bppp; + int index = (b >> nbits) & ((1 << bppp) - 1) & 127; + if (bytesPerPixel == 1) { + if (index >= colorPalette.length) { + Log.e(TAG, "zrlePlainRLEPixels palette lookup out of bounds " + index + " (0x" + + Integer.toHexString(index) + ")"); + } + zrleTilePixels[ptr++] = colorPalette[0xFF & palette[index]]; + } else { + zrleTilePixels[ptr++] = palette[index]; + } + } + } + } + + private void readZrlePlainRLEPixels(int tw, int th) throws Exception { + int ptr = 0; + int end = ptr + tw * th; + if (zrleTilePixels == null || end > zrleTilePixels.length) { + zrleTilePixels = new int[end]; + } + while (ptr < end) { + int pix = readPixel(zrleInStream); + int len = 1; + int b; + do { + b = zrleInStream.readU8(); + len += b; + } while (b == 255); + + if (!(len <= end - ptr)) { + throw new Exception("ZRLE decoder: assertion failed" + " (len <= end-ptr)"); + } + + if (bytesPerPixel == 1) { + while (len-- > 0) { + zrleTilePixels[ptr++] = colorPalette[0xFF & pix]; + } + } else { + while (len-- > 0) { + zrleTilePixels[ptr++] = pix; + } + } + } + } + + private void readZrlePackedRLEPixels(int tw, int th, int[] palette) throws Exception { + + int ptr = 0; + int end = ptr + tw * th; + if (zrleTilePixels == null || end > zrleTilePixels.length) { + zrleTilePixels = new int[end]; + } + while (ptr < end) { + int index = zrleInStream.readU8(); + int len = 1; + if ((index & 128) != 0) { + int b; + do { + b = zrleInStream.readU8(); + len += b; + } while (b == 255); + + if (!(len <= end - ptr)) { + throw new Exception("ZRLE decoder: assertion failed" + " (len <= end - ptr)"); + } + } + + index &= 127; + int pix = palette[index]; + + if (bytesPerPixel == 1) { + while (len-- > 0) { + zrleTilePixels[ptr++] = colorPalette[0xFF & pix]; + } + } else { + while (len-- > 0) { + zrleTilePixels[ptr++] = pix; + } + } + } + } + + // + // Copy pixels from zrleTilePixels8 or zrleTilePixels24, then update. + // + private void handleUpdatedZrleTile(int x, int y, int w, int h) { + int offsetSrc = 0; + int[] destPixels = bitmapData.bitmapPixels; + for (int j = 0; j < h; j++) { + System.arraycopy(zrleTilePixels, offsetSrc, destPixels, bitmapData.offset(x, y + j), w); + offsetSrc += w; + } + + bitmapData.updateBitmap(x, y, w, h); + } + + public void connected() { + VncCanvasActivity activity = (VncCanvasActivity) VncCanvas.this.getContext(); + activity.onConnected(); + + } + + + class VNCOnTouchListener implements View.OnTouchListener { + + @Override + public boolean onTouch(View v, MotionEvent event) { + // TODO Auto-generated method stub + //Log.i("VNCOnTouchListener", "onTouch"); + if(Config.mouseMode == Config.MouseMode.Trackpad) { + return false; + } + return processPointerEvent(event, event.getAction() == MotionEvent.ACTION_DOWN); + } + + + } + + class VNCGenericMotionListener_API12 implements View.OnGenericMotionListener { + private VncCanvas mSurface; + + // Generic Motion (mouse hover, joystick...) events go here + @Override + public boolean onGenericMotion(View v, MotionEvent event) { + float x, y; + int action; + + switch (event.getSource()) { + case InputDevice.SOURCE_JOYSTICK: + case InputDevice.SOURCE_GAMEPAD: + case InputDevice.SOURCE_DPAD: + return true; + case InputDevice.SOURCE_MOUSE: + if(Config.mouseMode == Config.MouseMode.Trackpad) + break; + + action = event.getActionMasked(); + //Log.d("SDL", "onGenericMotion, action = " + action + "," + event.getX() + ", " + event.getY()); + switch (action) { + case MotionEvent.ACTION_SCROLL: + x = event.getAxisValue(MotionEvent.AXIS_HSCROLL, 0); + y = event.getAxisValue(MotionEvent.AXIS_VSCROLL, 0); + //Log.d("SDL", "Mouse Scroll: " +event.getX() + ":" + event.getY() + " => " + x + "," + y); + + //TODO: + //SDLActivity.onSDLNativeMouse(0, action, x, y); + //processPointerEvent(event,false); + + // Log.v("Limbo", "Button Up"); + boolean scrollUp=false; + if (y > 0) + scrollUp = true; + else if (y < 0) + scrollUp = false; + + return processPointerEvent((int) event.getX(), (int) event.getY(), event.getAction(), event.getMetaState(), false, + false, false, scrollUp); + //return true; + + case MotionEvent.ACTION_HOVER_MOVE: + if(Config.processMouseHistoricalEvents) { + final int historySize = event.getHistorySize(); + for (int h = 0; h < historySize; h++) { + float ex = event.getHistoricalX(h); + float ey = event.getHistoricalY(h); + float ep = event.getHistoricalPressure(h); + processHoverMouse(event, ex, ey, ep, action); + } + } + + float ex = event.getX(); + float ey = event.getY(); + float ep = event.getPressure(); + processHoverMouse(event, ex, ey, ep, action); + return true; + + case MotionEvent.ACTION_UP: + + default: + break; + } + break; + + default: + break; + } + + // Event was not managed + return false; + } + + private void processHoverMouse(MotionEvent event, float x,float y,float p, int action) { + + //Log.d("VncCanvas", "Mouse Hover: " + x + "," + y); + + if(Config.mouseMode == Config.MouseMode.External) { + +// float x_margin = (SDLActivity.width - LimboSDLActivity.vm_width * LimboSDLActivity.height / (float) LimboSDLActivity.vm_height) / 2; +// if (x < x_margin) { +// return; +// } else if (x > SDLActivity.width - x_margin) { +// return; +// } + + //TODO: + //SDLActivity.onSDLNativeMouse(0, action, x, y); + processPointerEvent(event, false, false); + } +// else if (Config.mouseMode == Config.MouseMode.External_Alt){ +// processHoverMouseAlt(x, y, p, action); +// } + } + + } +} diff --git a/app/src/main/java/android/androidVNC/VncCanvasActivity.java b/app/src/main/java/android/androidVNC/VncCanvasActivity.java new file mode 100644 index 0000000..f36ffd3 --- /dev/null +++ b/app/src/main/java/android/androidVNC/VncCanvasActivity.java @@ -0,0 +1,1854 @@ +/* + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ +// +// CanvasView is the Activity for showing VNC Desktop. +// +package android.androidVNC; + +import android.app.Activity; +import android.app.Dialog; +import android.content.Context; +import android.content.DialogInterface; +import android.content.DialogInterface.OnDismissListener; +import android.content.Intent; +import android.content.res.Configuration; +import android.graphics.PointF; +import android.net.Uri; +import android.os.Bundle; +import android.os.SystemClock; +import android.util.Log; +import android.view.Display; +import android.view.KeyEvent; +import android.view.Menu; +import android.view.MenuItem; +import android.view.MotionEvent; +import android.view.View; +import android.view.Window; +import android.view.WindowManager; +import android.view.inputmethod.InputMethodManager; +import android.widget.AdapterView; +import android.widget.AdapterView.OnItemClickListener; +import android.widget.ArrayAdapter; +import android.widget.ListView; +import android.widget.Toast; +import android.widget.ZoomControls; + +import com.antlersoft.android.bc.BCFactory; +import com.vectras.qemu.Config; +import com.vectras.qemu.MainActivityCommon; +import com.vectras.vm.R; +import com.vectras.vm.utils.UIUtils; + +import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; + +import androidx.appcompat.app.AppCompatActivity; + +public class VncCanvasActivity extends AppCompatActivity { + + static Display display = null; + public static Activity activity; + + /** + * @author Michael A. MacDonald + */ + class ZoomInputHandler extends AbstractGestureInputHandler { + + /** + * In drag mode (entered with long press) you process mouse events + * without sending them through the gesture detector + */ + private boolean dragMode; + /** + * Key handler delegate that handles DPad-based mouse motion + */ + private DPadMouseKeyHandler keyHandler; + + /** + * @param c + */ + ZoomInputHandler() { + super(VncCanvasActivity.this); + keyHandler = new DPadMouseKeyHandler(VncCanvasActivity.this, vncCanvas.handler); + } + + /* + * (non-Javadoc) + * + * @see android.androidVNC.AbstractInputHandler#getHandlerDescription() + */ + @Override + public CharSequence getHandlerDescription() { + return getResources().getString(R.string.input_mode_touch_pan_zoom_mouse); + } + + /* + * (non-Javadoc) + * + * @see android.androidVNC.AbstractInputHandler#getName() + */ + @Override + public String getName() { + return TOUCH_ZOOM_MODE; + } + + /* + * (non-Javadoc) + * + * @see + * android.androidVNC.VncCanvasActivity.ZoomInputHandler#onKeyDown(int, + * android.view.KeyEvent) + */ + @Override + public boolean onKeyDown(int keyCode, KeyEvent evt) { + return keyHandler.onKeyDown(keyCode, evt); + } + + /* + * (non-Javadoc) + * + * @see + * android.androidVNC.VncCanvasActivity.ZoomInputHandler#onKeyUp(int, + * android.view.KeyEvent) + */ + @Override + public boolean onKeyUp(int keyCode, KeyEvent evt) { + return keyHandler.onKeyUp(keyCode, evt); + } + + /* + * (non-Javadoc) + * + * @see + * android.androidVNC.AbstractInputHandler#onTrackballEvent(android. + * view.MotionEvent) + */ + @Override + public boolean onTrackballEvent(MotionEvent evt) { + return trackballMouse(evt); + } + + /* + * (non-Javadoc) + * + * @see + * android.view.GestureDetector.SimpleOnGestureListener#onDown(android + * .view.MotionEvent) + */ + @Override + public boolean onDown(MotionEvent e) { + panner.stop(); + return true; + } + + /** + * Divide stated fling velocity by this amount to get initial velocity + * per pan interval + */ + static final float FLING_FACTOR = 8; + + /* + * (non-Javadoc) + * + * @see + * android.view.GestureDetector.SimpleOnGestureListener#onFling(android + * .view.MotionEvent, android.view.MotionEvent, float, float) + */ + @Override + public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { + showZoomer(false); + panner.start(-(velocityX / FLING_FACTOR), -(velocityY / FLING_FACTOR), new Panner.VelocityUpdater() { + + /* + * (non-Javadoc) + * + * @see android.androidVNC.Panner.VelocityUpdater#updateVelocity + * (android.graphics.Point, long) + */ + @Override + public boolean updateVelocity(PointF p, long interval) { + double scale = Math.pow(0.8, interval / 50.0); + p.x *= scale; + p.y *= scale; + return (Math.abs(p.x) > 0.5 || Math.abs(p.y) > 0.5); + } + }); + return true; + } + + /* + * (non-Javadoc) + * + * @see + * android.androidVNC.AbstractGestureInputHandler#onTouchEvent(android + * .view.MotionEvent) + */ + @Override + public boolean onTouchEvent(MotionEvent e) { + // MK + if (e.getAction() == MotionEvent.ACTION_CANCEL) + return true; + + if (dragMode) { + vncCanvas.changeTouchCoordinatesToFullFrame(e); + if (e.getAction() == MotionEvent.ACTION_UP) { + dragMode = false; + } + return vncCanvas.processPointerEvent(e, true); + } else { + return super.onTouchEvent(e); + } + } + + /* + * (non-Javadoc) + * + * @see + * android.view.GestureDetector.SimpleOnGestureListener#onLongPress( + * android.view.MotionEvent) + */ + @Override + public void onLongPress(MotionEvent e) { +// showZoomer(true); +// BCFactory.getInstance().getBCHaptic().performLongPressHaptic(vncCanvas); +// dragMode = true; +// vncCanvas.processPointerEvent(vncCanvas.changeTouchCoordinatesToFullFrame(e), true); + } + + /* + * (non-Javadoc) + * + * @see + * android.view.GestureDetector.SimpleOnGestureListener#onScroll(android + * .view.MotionEvent, android.view.MotionEvent, float, float) + */ + @Override + public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { + if (inScaling) { + return false; + } + showZoomer(false); + return vncCanvas.pan((int) distanceX, (int) distanceY); + } + + /* + * (non-Javadoc) + * + * @see android.view.GestureDetector.SimpleOnGestureListener# + * onSingleTapConfirmed (android.view.MotionEvent) + */ + @Override + public boolean onSingleTapConfirmed(MotionEvent e) { + vncCanvas.changeTouchCoordinatesToFullFrame(e); + vncCanvas.processPointerEvent(e, true); + e.setAction(MotionEvent.ACTION_UP); + return vncCanvas.processPointerEvent(e, false); + } + + /* + * (non-Javadoc) + * + * @see + * android.view.GestureDetector.SimpleOnGestureListener#onDoubleTap( + * android.view.MotionEvent) + */ + @Override + public boolean onDoubleTap(MotionEvent e) { + vncCanvas.changeTouchCoordinatesToFullFrame(e); + vncCanvas.processPointerEvent(e, true, true); + e.setAction(MotionEvent.ACTION_UP); + return vncCanvas.processPointerEvent(e, false, true); + } + } + + public class TouchpadInputHandler extends AbstractGestureInputHandler { + + /** + * In drag mode (entered with long press) you process mouse events + * without sending them through the gesture detector + */ + private boolean dragMode; + float dragX, dragY; + /** + * Key handler delegate that handles DPad-based mouse motion + */ + private DPadMouseKeyHandler keyHandler; + + TouchpadInputHandler() { + super(VncCanvasActivity.this); + keyHandler = new DPadMouseKeyHandler(VncCanvasActivity.this, vncCanvas.handler); + } + + /* + * (non-Javadoc) + * + * @see android.androidVNC.AbstractInputHandler#getHandlerDescription() + */ + @Override + public CharSequence getHandlerDescription() { + return getResources().getString(R.string.input_mode_touchpad); + } + + /* + * (non-Javadoc) + * + * @see android.androidVNC.AbstractInputHandler#getName() + */ + @Override + public String getName() { + return TOUCHPAD_MODE; + } + + /* + * (non-Javadoc) + * + * @see + * android.androidVNC.VncCanvasActivity.ZoomInputHandler#onKeyDown(int, + * android.view.KeyEvent) + */ + @Override + public boolean onKeyDown(int keyCode, KeyEvent evt) { + return keyHandler.onKeyDown(keyCode, evt); + } + + /* + * (non-Javadoc) + * + * @see + * android.androidVNC.VncCanvasActivity.ZoomInputHandler#onKeyUp(int, + * android.view.KeyEvent) + */ + @Override + public boolean onKeyUp(int keyCode, KeyEvent evt) { + return keyHandler.onKeyUp(keyCode, evt); + } + + /* + * (non-Javadoc) + * + * @see + * android.androidVNC.AbstractInputHandler#onTrackballEvent(android. + * view.MotionEvent) + */ + @Override + public boolean onTrackballEvent(MotionEvent evt) { + return trackballMouse(evt); + } + + /** + * scale down delta when it is small. This will allow finer control when + * user is making a small movement on touch screen. Scale up delta when + * delta is big. This allows fast mouse movement when user is flinging. + * + * @param deltaX + * @return + */ + private float fineCtrlScale(float delta) { + float sign = (delta > 0) ? 1 : -1; + delta = Math.abs(delta); + if (delta >= 1 && delta <= 3) { + delta = 1; + } else if (delta <= 10) { + delta *= 0.34; + } else if (delta <= 30) { + delta *= delta / 30; + } else if (delta <= 90) { + delta *= (delta / 30); + } else { + delta *= 3.0; + } + return sign * delta; + } + + /* + * (non-Javadoc) + * + * @see + * android.view.GestureDetector.SimpleOnGestureListener#onLongPress( + * android.view.MotionEvent) + */ + @Override + public void onLongPress(MotionEvent e) { + if(Config.enableDragOnLongPress) + dragPointer(e); + } + + private void dragPointer(MotionEvent e) { + + showZoomer(true); + BCFactory.getInstance().getBCHaptic().performLongPressHaptic(vncCanvas); + dragMode = true; + dragX = e.getX(); + dragY = e.getY(); + // send a mouse down event to the remote without moving the mouse. + remoteMouseStayPut(e); + vncCanvas.processPointerEvent(e, true); + + } + + /* + * (non-Javadoc) + * + * @see + * android.view.GestureDetector.SimpleOnGestureListener#onScroll(android + * .view.MotionEvent, android.view.MotionEvent, float, float) + */ + @Override + public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { + //LIMBO: Disable this for now +// if (BCFactory.getInstance().getBCMotionEvent().getPointerCount(e2) > 1) { +// if (inScaling) { +// return false; +// } +// showZoomer(true); +// return vncCanvas.pan((int) distanceX, (int) distanceY); +// } else { + // compute the relative movement offset on the remote screen. + float deltaX = -distanceX * vncCanvas.getScale(); + float deltaY = -distanceY * vncCanvas.getScale(); + deltaX = fineCtrlScale(deltaX); + deltaY = fineCtrlScale(deltaY); + + // compute the absolution new mouse pos on the remote site. + float newRemoteX = vncCanvas.mouseX + deltaX; + float newRemoteY = vncCanvas.mouseY + deltaY; + + if (dragMode) { + if (e2.getAction() == MotionEvent.ACTION_UP) { + dragMode = false; + } + dragX = e2.getX(); + dragY = e2.getY(); + e2.setLocation(newRemoteX, newRemoteY); + return vncCanvas.processPointerEvent(e2, true); + } else { + e2.setLocation(newRemoteX, newRemoteY); + vncCanvas.processPointerEvent(e2, false); + } +// } + return true; + } + + /* + * (non-Javadoc) + * + * @see + * android.androidVNC.AbstractGestureInputHandler#onTouchEvent(android + * .view.MotionEvent) + */ + @Override + public boolean onTouchEvent(MotionEvent e) { + + // MK + if (e.getAction() == MotionEvent.ACTION_CANCEL) + return true; + + if (Config.mouseMode == Config.MouseMode.External) { + return true; + } + // if (e.getPointerCount() > 1) { + // // Log.v("Limbo", "Detected 2 finger tap in onTouchEvent"); + // rightClick(e); + // return true; + // } + + // compute the relative movement offset on the remote screen. + float deltaX = (e.getX() - dragX) * vncCanvas.getScale(); + float deltaY = (e.getY() - dragY) * vncCanvas.getScale(); + dragX = e.getX(); + dragY = e.getY(); + deltaX = fineCtrlScale(deltaX); + deltaY = fineCtrlScale(deltaY); + + // compute the absolution new mouse pos on the remote site. + float newRemoteX = vncCanvas.mouseX + deltaX; + float newRemoteY = vncCanvas.mouseY + deltaY; + + if (dragMode) { + boolean down = false; + if (e.getAction() == MotionEvent.ACTION_UP) { + dragMode = false; + } else if (e.getAction() == MotionEvent.ACTION_DOWN) { + down = true; + } + + e.setLocation(newRemoteX, newRemoteY); + vncCanvas.processPointerEvent(e, down); + return super.onTouchEvent(e); + + } else if (!Config.enableDragOnLongPress && e.getAction() == MotionEvent.ACTION_MOVE) { + e.setLocation(newRemoteX, newRemoteY); + return vncCanvas.processPointerEvent(e, false); + } else { + return super.onTouchEvent(e); + } + } + + public boolean rightClick(final MotionEvent e) { + Thread t = new Thread(new Runnable() { + public void run() { + remoteMouseStayPut(e); + // One + // Log.v("Double Click", "One"); + vncCanvas.processPointerEvent(e, true, true); + try { + Thread.sleep(100); + } catch (InterruptedException ex) { + Logger.getLogger(VncCanvasActivity.class.getName()).log(Level.SEVERE, null, ex); + } + e.setAction(MotionEvent.ACTION_UP); + vncCanvas.processPointerEvent(e, false, true); + } + }); + // t.setPriority(Thread.MAX_PRIORITY); + t.start(); + return true; + + } + + /** + * Modify the event so that it does not move the mouse on the remote + * server. + * + * @param e + */ + private void remoteMouseStayPut(MotionEvent e) { + e.setLocation(vncCanvas.mouseX, vncCanvas.mouseY); + + } + + /* + * (non-Javadoc) confirmed single tap: do a single mouse click on remote + * without moving the mouse. + * + * @see android.view.GestureDetector.SimpleOnGestureListener# + * onSingleTapConfirmed (android.view.MotionEvent) + */ + + @Override + public boolean onSingleTapConfirmed(MotionEvent e) { + singleClick(e); + return true; + // boolean multiTouch = + // (BCFactory.getInstance().getBCMotionEvent().getPointerCount(e) > + // 1); + // remoteMouseStayPut(e); + // vncCanvas.processPointerEvent(e, true, multiTouch || + // vncCanvas.cameraButtonDown); + // e.setAction(MotionEvent.ACTION_UP); + // return vncCanvas.processPointerEvent(e, false, multiTouch || + // vncCanvas.cameraButtonDown); + } + + private boolean singleClick(final MotionEvent e) { + Thread t = new Thread(new Runnable() { + public void run() { + remoteMouseStayPut(e); + // One + // Log.v("Double Click", "One"); + vncCanvas.processPointerEvent(e, true, false); + try { + Thread.sleep(50); + } catch (InterruptedException ex) { + Logger.getLogger(VncCanvasActivity.class.getName()).log(Level.SEVERE, null, ex); + } + e.setAction(MotionEvent.ACTION_UP); + vncCanvas.processPointerEvent(e, false, false); + } + }); + // t.setPriority(Thread.MAX_PRIORITY); + t.start(); + return true; + + } + + private boolean middleClick(final MotionEvent e) { + Thread t = new Thread(new Runnable() { + public void run() { + remoteMouseStayPut(e); + // One + // Log.v("Double Click", "One"); + //vncCanvas.processPointerEvent(e, true, false); + vncCanvas.processPointerEvent((int) e.getX(), (int) e.getY(), e.getAction(), 0, true, false, true, false); + try { + Thread.sleep(50); + } catch (InterruptedException ex) { + Logger.getLogger(VncCanvasActivity.class.getName()).log(Level.SEVERE, null, ex); + } + e.setAction(MotionEvent.ACTION_UP); + //vncCanvas.processPointerEvent(e, false, false); + vncCanvas.processPointerEvent((int) e.getX(), (int) e.getY(), e.getAction(), 0, false, false, true, false); + } + }); + // t.setPriority(Thread.MAX_PRIORITY); + t.start(); + return true; + + } + + /* + * (non-Javadoc) double tap: do two left mouse right mouse clicks on + * remote without moving the mouse. + * + * @see + * android.view.GestureDetector.SimpleOnGestureListener#onDoubleTap( + * android.view.MotionEvent) + */ + @Override + public boolean onDoubleTap(MotionEvent e) { + if(!Config.enableDragOnLongPress) + processDoubleTap(e); + else + doubleClick(e); + return false; + + } + + private void processDoubleTap(final MotionEvent e) { + Thread t = new Thread(new Runnable() { + public void run() { + try { + Thread.sleep(400); + } catch (InterruptedException e1) { + e1.printStackTrace(); + } + + if (vncCanvas.mouseDown) { +// panner.stop(); + dragPointer(e); + } else + doubleClick(e); + + } + }); + t.start(); + } + + /* + * (non-Javadoc) + * + * @see + * android.view.GestureDetector.SimpleOnGestureListener#onDown(android + * .view.MotionEvent) + */ + @Override + public boolean onDown(MotionEvent e) { + panner.stop(); + return true; + } + + private Object doubleClickLock = new Object(); + + private boolean doubleClick(final MotionEvent e1) { + Thread t = new Thread(new Runnable() { + public void run() { + synchronized (doubleClickLock) { + + //XXX: We make a copy of the event because we have some + // race condition here updating mouseX, mouseY + MotionEvent event = MotionEvent.obtain(e1.getDownTime(), + e1.getEventTime(), e1.getAction(), + e1.getX(), e1.getY(), e1.getMetaState()); + + remoteMouseStayPut(event); + // One + // Log.v("Double Click", "One"); + vncCanvas.processPointerEvent(event, true, false); + try { + Thread.sleep(50); + } catch (InterruptedException ex) { + Logger.getLogger(VncCanvasActivity.class.getName()).log(Level.SEVERE, null, ex); + } + event.setAction(MotionEvent.ACTION_UP); + vncCanvas.processPointerEvent(event, false, false); + try { + Thread.sleep(50); + } catch (InterruptedException ex) { + Logger.getLogger(VncCanvasActivity.class.getName()).log(Level.SEVERE, null, ex); + } + // Two + // Log.v("Double Click", "Two"); + event.setAction(MotionEvent.ACTION_DOWN); + vncCanvas.processPointerEvent(event, true, false); + try { + Thread.sleep(50); + } catch (InterruptedException ex) { + Logger.getLogger(VncCanvasActivity.class.getName()).log(Level.SEVERE, null, ex); + } + event.setAction(MotionEvent.ACTION_UP); + vncCanvas.processPointerEvent(event, false, false); + } + } + }); + // t.setPriority(Thread.MAX_PRIORITY); + t.start(); + return true; + + } + } + + private final static String TAG = "VncCanvasActivity"; + public AbstractInputHandler inputHandler; + public VncCanvas vncCanvas; + + public MenuItem[] inputModeMenuItems; + public AbstractInputHandler inputModeHandlers[]; + public ConnectionBean connection; + public boolean trackballButtonDown; + public static final int inputModeIds[] = { R.id.itemInputFitToScreen, R.id.itemInputTouchpad, R.id.itemInputMouse, + R.id.itemInputPan, R.id.itemInputTouchPanTrackballMouse, R.id.itemInputDPadPanTouchMouse, + R.id.itemInputTouchPanZoomMouse }; + ZoomControls zoomer; + Panner panner; + + @Override + public void onCreate(Bundle icicle) { + + super.onCreate(icicle); + activity = this; + + Intent i = getIntent(); + connection = new ConnectionBean(); + Uri data = i.getData(); + if ((data != null) && (data.getScheme().equals("vnc"))) { + String host = data.getHost(); + // This should not happen according to Uri contract, but bug + // introduced in Froyo (2.2) + // has made this parsing of host necessary + int index = host.indexOf(':'); + int port; + if (index != -1) { + try { + port = Integer.parseInt(host.substring(index + 1)); + } catch (NumberFormatException nfe) { + port = 0; + } + host = host.substring(0, index); + } else { + port = data.getPort(); + } + if (host.equals(VncConstants.CONNECTION)) { + ConnectionBean bean = new ConnectionBean(); + if (bean != null) { + bean.setConnectionId(connection.get_Id()); + } + } else { + connection.setAddress(host); + connection.setNickname(connection.getAddress()); + connection.setPort(port); + List path = data.getPathSegments(); + if (path.size() >= 1) { + connection.setColorModel(path.get(1)); + } + if (path.size() >= 2) { + connection.setPassword(path.get(1)); + } + } + } else { + + Bundle extras = i.getExtras(); + + if (connection.getPort() == 0) { + connection.setPort(5901); + } + + // Parse a HOST:PORT entry + String host = connection.getAddress(); + // if (host.indexOf(':') > -1) { + // String p = host.substring(host.indexOf(':') + 1); + // try { + // connection.setPort(Integer.parseInt(p)); + // } catch (Exception e) { + // } + // connection.setAddress(host.substring(0, host.indexOf(':'))); + // } + } + connection.setPassword(MainActivityCommon.getVnc_passwd()); + setContentView(); + + vncCanvas = (VncCanvas) findViewById(R.id.vnc_canvas); + zoomer = (ZoomControls) findViewById(R.id.zoomer); + + vncCanvas.initializeVncCanvas(connection, new Runnable() { + public void run() { + setModes(); + } + }); + zoomer.hide(); + zoomer.setOnZoomInClickListener(new View.OnClickListener() { + + /* + * (non-Javadoc) + * + * @see android.view.View.OnClickListener#onClick(android.view.View) + */ + @Override + public void onClick(View v) { + showZoomer(true); + vncCanvas.scaling.zoomIn(VncCanvasActivity.this); + + } + }); + zoomer.setOnZoomOutClickListener(new View.OnClickListener() { + + /* + * (non-Javadoc) + * + * @see android.view.View.OnClickListener#onClick(android.view.View) + */ + @Override + public void onClick(View v) { + showZoomer(true); + vncCanvas.scaling.zoomOut(VncCanvasActivity.this); + + } + }); + zoomer.setOnZoomInClickListener(new View.OnClickListener() { + + /* + * (non-Javadoc) + * + * @see android.view.View.OnClickListener#onClick(android.view.View) + */ + @Override + public void onClick(View v) { + InputMethodManager inputMgr = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); + inputMgr.toggleSoftInput(0, 0); + } + }); + zoomer.setOnZoomOutClickListener(new View.OnClickListener() { + + /* + * (non-Javadoc) + * + * @see android.view.View.OnClickListener#onClick(android.view.View) + */ + @Override + public void onClick(View v) { + InputMethodManager inputMgr = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); + inputMgr.toggleSoftInput(0, 0); + } + }); + panner = new Panner(this, vncCanvas.handler); + + inputHandler = getInputHandlerById(R.id.itemInputFitToScreen); + + display = ((WindowManager) this.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay(); + } + + public void setContentView() { + setContentView(R.layout.activity_vnc); + } + + /** + * Set modes on start to match what is specified in the ConnectionBean; + * color mode (already done) scaling, input mode + */ + void setModes() { + AbstractInputHandler handler = getInputHandlerByName(connection.getInputMode()); + AbstractScaling.getByScaleType(connection.getScaleMode()).setScaleTypeForActivity(this); + this.inputHandler = handler; + showPanningState(); + } + + ConnectionBean getConnection() { + return connection; + } + + /* + * (non-Javadoc) + * + * @see android.app.Activity#onPrepareDialog(int, android.app.Dialog) + */ + @Override + protected void onPrepareDialog(int id, Dialog dialog) { + super.onPrepareDialog(id, dialog); + if (dialog instanceof ConnectionSettable) { + ((ConnectionSettable) dialog).setConnection(connection); + } + } + + @Override + public void onConfigurationChanged(Configuration newConfig) { + // ignore orientation/keyboard change + super.onConfigurationChanged(newConfig); + } + + @Override + protected void onStop() { + vncCanvas.disableRepaints(); + super.onStop(); + } + + @Override + protected void onRestart() { + vncCanvas.enableRepaints(); + super.onRestart(); + } + + /** + * {@inheritDoc} + */ + @Override + public boolean onCreateOptionsMenu(Menu menu) { + getMenuInflater().inflate(R.menu.vnccanvasactivitymenu, menu); + + if (vncCanvas.scaling != null) { + menu.findItem(vncCanvas.scaling.getId()).setChecked(true); + } + + Menu inputMenu = menu.findItem(R.id.itemInputMode).getSubMenu(); + + inputModeMenuItems = new MenuItem[inputModeIds.length]; + for (int i = 0; i < inputModeIds.length; i++) { + inputModeMenuItems[i] = inputMenu.findItem(inputModeIds[i]); + } + updateInputMenu(); + return true; + } + + /** + * Change the input mode sub-menu to reflect change in scaling + */ + public void updateInputMenu() { + if (inputModeMenuItems == null || vncCanvas.scaling == null) { + return; + } + for (MenuItem item : inputModeMenuItems) { + item.setEnabled(vncCanvas.scaling.isValidInputMode(item.getItemId())); + if (getInputHandlerById(item.getItemId()) == inputHandler) { + item.setChecked(true); + } + } + } + + + + /** + * If id represents an input handler, return that; otherwise return null + * + * @param id + * @return + */ + public AbstractInputHandler getInputHandlerById(int id) { + if (inputModeHandlers == null) { + inputModeHandlers = new AbstractInputHandler[inputModeIds.length]; + } + for (int i = 0; i < inputModeIds.length; ++i) { + if (inputModeIds[i] == id) { + if (inputModeHandlers[i] == null) { + if (id == R.id.itemInputFitToScreen) + inputModeHandlers[i] = new FitToScreenMode(); + else if (id == R.id.itemInputPan) + inputModeHandlers[i] = new PanMode(); + else if (id == R.id.itemInputMouse) + inputModeHandlers[i] = new MouseMode(); + + else if (id == R.id.itemInputTouchPanTrackballMouse) + inputModeHandlers[i] = new TouchPanTrackballMouse(); + else if (id == R.id.itemInputDPadPanTouchMouse) + inputModeHandlers[i] = new DPadPanTouchMouseMode(); + + else if (id == R.id.itemInputTouchPanZoomMouse) + inputModeHandlers[i] = new ZoomInputHandler(); + + else if (id == R.id.itemInputTouchpad) + inputModeHandlers[i] = new TouchpadInputHandler(); + } + + return inputModeHandlers[i]; + } + } + return null; + } + + AbstractInputHandler getInputHandlerByName(String name) { + AbstractInputHandler result = null; + for (int id : inputModeIds) { + AbstractInputHandler handler = getInputHandlerById(id); + if (handler.getName().equals(name)) { + result = handler; + break; + } + } + if (result == null) { + result = getInputHandlerById(R.id.itemInputTouchPanZoomMouse); + } + return result; + } + + int getModeIdFromHandler(AbstractInputHandler handler) { + for (int id : inputModeIds) { + if (handler == getInputHandlerById(id)) { + return id; + } + } + return R.id.itemInputTouchPanZoomMouse; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + vncCanvas.afterMenu = true; + if (item.getItemId() == R.id.itemSpecialKeys) { + showDialog(R.layout.metakey); + return true; + }else if (item.getItemId() == R.id.itemColorMode) { + selectColorModel(); + return true; + } + // Following sets one of the scaling options + else if (item.getItemId() == R.id.itemZoomable || + item.getItemId() == R.id.itemOneToOne || + item.getItemId() == R.id.itemFitToScreen) { + AbstractScaling.getById(item.getItemId()).setScaleTypeForActivity(this); + item.setChecked(true); + showPanningState(); + return true; + } + // case R.id.itemCenterMouse: + // vncCanvas.warpMouse(vncCanvas.absoluteXPosition + // + vncCanvas.getVisibleWidth() / 2, + // vncCanvas.absoluteYPosition + vncCanvas.getVisibleHeight() + // / 2); + // return true; + else if (item.getItemId() == R.id.itemReconnect){ + vncCanvas.closeConnection(); + vncCanvas.reload(); + return true; + } else if (item.getItemId() == R.id.itemDisconnect){ + vncCanvas.closeConnection(); + finish(); + return true; + } else if (item.getItemId() == R.id.itemEnterText){ + showDialog(R.layout.entertext); + return true; + }else if (item.getItemId() == R.id.itemCtrlC) { + vncCanvas.sendMetaKey(MetaKeyBean.keyCtrlC); + return true; + }else if (item.getItemId() == R.id.itemCtrlAltDel){ + vncCanvas.sendMetaKey(MetaKeyBean.keyCtrlAltDel); + return true; + } + // case R.id.itemFollowMouse: + // vncCanvas.panToMouse(); + // return true; + // case R.id.itemFollowPan: + // return true; + // case R.id.itemArrowLeft: + // vncCanvas.sendMetaKey(MetaKeyBean.keyArrowLeft); + // return true; + // case R.id.itemArrowUp: + // vncCanvas.sendMetaKey(MetaKeyBean.keyArrowUp); + // return true; + // case R.id.itemArrowRight: + // vncCanvas.sendMetaKey(MetaKeyBean.keyArrowRight); + // return true; + // case R.id.itemArrowDown: + // vncCanvas.sendMetaKey(MetaKeyBean.keyArrowDown); + // return true; + else if (item.getItemId() == R.id.itemSendKeyAgain) { + return true; + }else if (item.getItemId() == R.id.itemOpenDoc){ + Utils.showDocumentation(this); + return true; + }else { + AbstractInputHandler input = getInputHandlerById(item.getItemId()); + if (input != null) { + inputHandler = input; + connection.setInputMode(input.getName()); + item.setChecked(true); + showPanningState(); + return true; + } + } + return super.onOptionsItemSelected(item); + } + + private MetaKeyBean lastSentKey; + + @Override + protected void onDestroy() { + super.onDestroy(); + if (isFinishing()) { + vncCanvas.closeConnection(); + vncCanvas.onDestroy(); + + + } + } + + @Override + public boolean onKeyDown(int keyCode, KeyEvent evt) { + if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) { + MotionEvent e = MotionEvent.obtain(1000, 1000, MotionEvent.ACTION_DOWN, vncCanvas.mouseX, vncCanvas.mouseY, + 0); + ((TouchpadInputHandler) this.inputHandler).rightClick(e); + return true; + } else if (keyCode == KeyEvent.KEYCODE_VOLUME_UP) { + MotionEvent e = MotionEvent.obtain(1000, 1000, MotionEvent.ACTION_DOWN, vncCanvas.mouseX, vncCanvas.mouseY, + 0); + ((TouchpadInputHandler) this.inputHandler).middleClick(e); + return true; + } else if (keyCode == KeyEvent.KEYCODE_MENU) { + return super.onKeyDown(keyCode, evt); + } + + return inputHandler.onKeyDown(keyCode, evt); + } + + @Override + public boolean onKeyUp(int keyCode, KeyEvent evt) { + if (keyCode == KeyEvent.KEYCODE_MENU) { + return super.onKeyUp(keyCode, evt); + } + + return inputHandler.onKeyUp(keyCode, evt); + } + + public void showPanningState() { + // Toast.makeText(this, inputHandler.getHandlerDescription(), + // Toast.LENGTH_SHORT).show(); + } + + /* + * (non-Javadoc) + * + * @see android.app.Activity#onTrackballEvent(android.view.MotionEvent) + */ + @Override + public boolean onTrackballEvent(MotionEvent event) { + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + trackballButtonDown = true; + break; + case MotionEvent.ACTION_UP: + trackballButtonDown = false; + break; + } + return inputHandler.onTrackballEvent(event); + } + + @Override + public boolean onTouchEvent(MotionEvent event) { + // MK + if (event.getAction() == MotionEvent.ACTION_CANCEL) + return true; + + if(event.getAction() == MotionEvent.ACTION_DOWN) + vncCanvas.mouseDown = true; + else if(event.getAction() == MotionEvent.ACTION_UP) + vncCanvas.mouseDown = false; + + return inputHandler.onTouchEvent(event); + } + + protected void selectColorModel() { + // Stop repainting the desktop + // because the display is composited! + vncCanvas.disableRepaints(); + + String[] choices = new String[COLORMODEL.values().length]; + int currentSelection = -1; + for (int i = 0; i < choices.length; i++) { + COLORMODEL cm = COLORMODEL.values()[i]; + choices[i] = cm.toString(); + if (vncCanvas.isColorModel(cm)) { + currentSelection = i; + } + } + + final Dialog dialog = new Dialog(this); + dialog.requestWindowFeature(Window.FEATURE_NO_TITLE); + ListView list = new ListView(this); + list.setAdapter(new ArrayAdapter(this, android.R.layout.simple_list_item_checked, choices)); + list.setChoiceMode(ListView.CHOICE_MODE_SINGLE); + list.setItemChecked(currentSelection, true); + list.setOnItemClickListener(new OnItemClickListener() { + public void onItemClick(AdapterView arg0, View arg1, int arg2, long arg3) { + if (dialog.isShowing()) { + dialog.dismiss(); + } + COLORMODEL cm = COLORMODEL.values()[arg2]; + vncCanvas.setColorModel(cm); + connection.setColorModel(cm.nameString()); + UIUtils.toastShort(VncCanvasActivity.this, "Updating Color Model to " + cm.toString()); + } + }); + dialog.setOnDismissListener(new OnDismissListener() { + @Override + public void onDismiss(DialogInterface arg0) { + Log.i(TAG, "Color Model Selector dismissed"); + // Restore desktop repaints + vncCanvas.enableRepaints(); + } + }); + dialog.setContentView(list); + dialog.show(); + } + + float panTouchX, panTouchY; + + /** + * Pan based on touch motions + * + * @param event + */ + private boolean pan(MotionEvent event) { + float curX = event.getX(); + float curY = event.getY(); + int dX = (int) (panTouchX - curX); + int dY = (int) (panTouchY - curY); + + return vncCanvas.pan(dX, dY); + } + + boolean defaultKeyDownHandler(int keyCode, KeyEvent evt) { + if (vncCanvas.processLocalKeyEvent(keyCode, evt)) { + return true; + } + return super.onKeyDown(keyCode, evt); + } + + boolean defaultKeyUpHandler(int keyCode, KeyEvent evt) { + if (vncCanvas.processLocalKeyEvent(keyCode, evt)) { + return true; + } + return super.onKeyUp(keyCode, evt); + } + + boolean touchPan(MotionEvent event) { + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + panTouchX = event.getX(); + panTouchY = event.getY(); + break; + case MotionEvent.ACTION_MOVE: + pan(event); + panTouchX = event.getX(); + panTouchY = event.getY(); + break; + case MotionEvent.ACTION_UP: + pan(event); + break; + } + return true; + } + + private static int convertTrackballDelta(double delta) { + return (int) Math.pow(Math.abs(delta) * 6.01, 2.5) * (delta < 0.0 ? -1 : 1); + } + + boolean trackballMouse(MotionEvent evt) { + // MK + if (evt.getAction() == MotionEvent.ACTION_CANCEL) + return false; + + int dx = convertTrackballDelta(evt.getX()); + int dy = convertTrackballDelta(evt.getY()); + + evt.offsetLocation(vncCanvas.mouseX + dx - evt.getX(), vncCanvas.mouseY + dy - evt.getY()); + + if (vncCanvas.processPointerEvent(evt, trackballButtonDown)) { + return true; + } + return VncCanvasActivity.super.onTouchEvent(evt); + } + + long hideZoomAfterMs; + static final long ZOOM_HIDE_DELAY_MS = 2500; + HideZoomRunnable hideZoomInstance = new HideZoomRunnable(); + + private void showZoomer(boolean force) { + + if (force || zoomer.getVisibility() != View.VISIBLE) { + // zoomer.show(); + hideZoomAfterMs = SystemClock.uptimeMillis() + ZOOM_HIDE_DELAY_MS; + vncCanvas.handler.postAtTime(hideZoomInstance, hideZoomAfterMs + 10); + } + } + + private class HideZoomRunnable implements Runnable { + + public void run() { + if (SystemClock.uptimeMillis() >= hideZoomAfterMs) { + zoomer.hide(); + } + } + } + + /** + * Touches and dpad (trackball) pan the screen + * + * @author Michael A. MacDonald + * + */ + class PanMode implements AbstractInputHandler { + + /* + * (non-Javadoc) + * + * @see android.androidVNC.AbstractInputHandler#onKeyDown(int, + * android.view.KeyEvent) + */ + @Override + public boolean onKeyDown(int keyCode, KeyEvent evt) { + // DPAD KeyDown events are move MotionEvents in Panning Mode + final int dPos = 100; + boolean result = false; + // MK + if (evt.getAction() == MotionEvent.ACTION_CANCEL) + return true; + + switch (keyCode) { + case KeyEvent.KEYCODE_DPAD_CENTER: + result = true; + break; + case KeyEvent.KEYCODE_DPAD_LEFT: + onTouchEvent(MotionEvent.obtain(1, System.currentTimeMillis(), MotionEvent.ACTION_MOVE, + panTouchX + dPos, panTouchY, 0)); + result = true; + break; + case KeyEvent.KEYCODE_DPAD_RIGHT: + onTouchEvent(MotionEvent.obtain(1, System.currentTimeMillis(), MotionEvent.ACTION_MOVE, + panTouchX - dPos, panTouchY, 0)); + result = true; + break; + case KeyEvent.KEYCODE_DPAD_UP: + onTouchEvent(MotionEvent.obtain(1, System.currentTimeMillis(), MotionEvent.ACTION_MOVE, panTouchX, + panTouchY + dPos, 0)); + result = true; + break; + case KeyEvent.KEYCODE_DPAD_DOWN: + onTouchEvent(MotionEvent.obtain(1, System.currentTimeMillis(), MotionEvent.ACTION_MOVE, panTouchX, + panTouchY - dPos, 0)); + result = true; + break; + default: + result = defaultKeyDownHandler(keyCode, evt); + break; + } + return result; + } + + /* + * (non-Javadoc) + * + * @see android.androidVNC.AbstractInputHandler#onKeyUp(int, + * android.view.KeyEvent) + */ + @Override + public boolean onKeyUp(int keyCode, KeyEvent evt) { + // Ignore KeyUp events for DPAD keys in Panning Mode; trackball + // button switches to mouse mode + switch (keyCode) { + case KeyEvent.KEYCODE_DPAD_CENTER: + inputHandler = getInputHandlerById(R.id.itemInputMouse); + connection.setInputMode(inputHandler.getName()); + updateInputMenu(); + showPanningState(); + return true; + case KeyEvent.KEYCODE_DPAD_LEFT: + return true; + case KeyEvent.KEYCODE_DPAD_RIGHT: + return true; + case KeyEvent.KEYCODE_DPAD_UP: + return true; + case KeyEvent.KEYCODE_DPAD_DOWN: + return true; + } + return defaultKeyUpHandler(keyCode, evt); + } + + /* + * (non-Javadoc) + * + * @see + * android.androidVNC.AbstractInputHandler#onTouchEvent(android.view + * .MotionEvent) + */ + @Override + public boolean onTouchEvent(MotionEvent event) { + // MK + if (event.getAction() == MotionEvent.ACTION_CANCEL) + return true; + + return touchPan(event); + } + + /* + * (non-Javadoc) + * + * @see + * android.androidVNC.AbstractInputHandler#onTrackballEvent(android. + * view.MotionEvent) + */ + @Override + public boolean onTrackballEvent(MotionEvent evt) { + return false; + } + + /* + * (non-Javadoc) + * + * @see android.androidVNC.AbstractInputHandler#handlerDescription() + */ + @Override + public CharSequence getHandlerDescription() { + return getResources().getText(R.string.input_mode_panning); + } + + /* + * (non-Javadoc) + * + * @see android.androidVNC.AbstractInputHandler#getName() + */ + @Override + public String getName() { + return "PAN_MODE"; + } + } + + /** + * The touchscreen pans the screen; the trackball moves and clicks the + * mouse. + * + * @author Michael A. MacDonald + * + */ + public class TouchPanTrackballMouse implements AbstractInputHandler { + + private DPadMouseKeyHandler keyHandler = new DPadMouseKeyHandler(VncCanvasActivity.this, vncCanvas.handler); + + /* + * (non-Javadoc) + * + * @see android.androidVNC.AbstractInputHandler#onKeyDown(int, + * android.view.KeyEvent) + */ + @Override + public boolean onKeyDown(int keyCode, KeyEvent evt) { + return keyHandler.onKeyDown(keyCode, evt); + } + + /* + * (non-Javadoc) + * + * @see android.androidVNC.AbstractInputHandler#onKeyUp(int, + * android.view.KeyEvent) + */ + @Override + public boolean onKeyUp(int keyCode, KeyEvent evt) { + return keyHandler.onKeyUp(keyCode, evt); + } + + /* + * (non-Javadoc) + * + * @see + * android.androidVNC.AbstractInputHandler#onTouchEvent(android.view + * .MotionEvent) + */ + @Override + public boolean onTouchEvent(MotionEvent evt) { + // MK + if (evt.getAction() == MotionEvent.ACTION_CANCEL) + return true; + + return touchPan(evt); + } + + /* + * (non-Javadoc) + * + * @see + * android.androidVNC.AbstractInputHandler#onTrackballEvent(android. + * view.MotionEvent) + */ + @Override + public boolean onTrackballEvent(MotionEvent evt) { + return trackballMouse(evt); + } + + /* + * (non-Javadoc) + * + * @see android.androidVNC.AbstractInputHandler#handlerDescription() + */ + @Override + public CharSequence getHandlerDescription() { + return getResources().getText(R.string.input_mode_touchpad_pan_trackball_mouse); + } + + /* + * (non-Javadoc) + * + * @see android.androidVNC.AbstractInputHandler#getName() + */ + @Override + public String getName() { + return "TOUCH_PAN_TRACKBALL_MOUSE"; + } + } + + public static final String FIT_SCREEN_NAME = "FIT_SCREEN"; + /** + * Internal name for default input mode with Zoom scaling + */ + public static final String TOUCH_ZOOM_MODE = "TOUCH_ZOOM_MODE"; + public static final String TOUCHPAD_MODE = "TOUCHPAD_MODE"; + + /** + * In fit-to-screen mode, no panning. Trackball and touchscreen work as + * mouse. + * + * @author Michael A. MacDonald + * + */ + public class FitToScreenMode implements AbstractInputHandler { + + private DPadMouseKeyHandler keyHandler = new DPadMouseKeyHandler(VncCanvasActivity.this, vncCanvas.handler); + + /* + * (non-Javadoc) + * + * @see android.androidVNC.AbstractInputHandler#onKeyDown(int, + * android.view.KeyEvent) + */ + @Override + public boolean onKeyDown(int keyCode, KeyEvent evt) { + return keyHandler.onKeyDown(keyCode, evt); + } + + /* + * (non-Javadoc) + * + * @see android.androidVNC.AbstractInputHandler#onKeyUp(int, + * android.view.KeyEvent) + */ + @Override + public boolean onKeyUp(int keyCode, KeyEvent evt) { + return keyHandler.onKeyUp(keyCode, evt); + } + + /* + * (non-Javadoc) + * + * @see + * android.androidVNC.AbstractInputHandler#onTouchEvent(android.view + * .MotionEvent) + */ + @Override + public boolean onTouchEvent(MotionEvent evt) { + // MK + if (evt.getAction() == MotionEvent.ACTION_CANCEL) + return true; + + return false; + } + + /* + * (non-Javadoc) + * + * @see + * android.androidVNC.AbstractInputHandler#onTrackballEvent(android. + * view.MotionEvent) + */ + @Override + public boolean onTrackballEvent(MotionEvent evt) { + return trackballMouse(evt); + } + + /* + * (non-Javadoc) + * + * @see android.androidVNC.AbstractInputHandler#handlerDescription() + */ + @Override + public CharSequence getHandlerDescription() { + return getResources().getText(R.string.input_mode_fit_to_screen); + } + + /* + * (non-Javadoc) + * + * @see android.androidVNC.AbstractInputHandler#getName() + */ + @Override + public String getName() { + return FIT_SCREEN_NAME; + } + } + + /** + * Touch screen controls, clicks the mouse. + * + * @author Michael A. MacDonald + * + */ + class MouseMode implements AbstractInputHandler { + + /* + * (non-Javadoc) + * + * @see android.androidVNC.AbstractInputHandler#onKeyDown(int, + * android.view.KeyEvent) + */ + @Override + public boolean onKeyDown(int keyCode, KeyEvent evt) { + if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) { + return true; + } + return defaultKeyDownHandler(keyCode, evt); + } + + /* + * (non-Javadoc) + * + * @see android.androidVNC.AbstractInputHandler#onKeyUp(int, + * android.view.KeyEvent) + */ + @Override + public boolean onKeyUp(int keyCode, KeyEvent evt) { + if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) { + inputHandler = getInputHandlerById(R.id.itemInputPan); + showPanningState(); + connection.setInputMode(inputHandler.getName()); + updateInputMenu(); + return true; + } + return defaultKeyUpHandler(keyCode, evt); + } + + /* + * (non-Javadoc) + * + * @see + * android.androidVNC.AbstractInputHandler#onTouchEvent(android.view + * .MotionEvent) + */ + @Override + public boolean onTouchEvent(MotionEvent event) { + // Mouse Pointer Control Mode + // Pointer event is absolute coordinates. + + // MK + if (event.getAction() == MotionEvent.ACTION_CANCEL) + return true; + + vncCanvas.changeTouchCoordinatesToFullFrame(event); + if (vncCanvas.processPointerEvent(event, true)) { + return true; + } + return VncCanvasActivity.super.onTouchEvent(event); + } + + /* + * (non-Javadoc) + * + * @see + * android.androidVNC.AbstractInputHandler#onTrackballEvent(android. + * view.MotionEvent) + */ + @Override + public boolean onTrackballEvent(MotionEvent evt) { + return false; + } + + /* + * (non-Javadoc) + * + * @see android.androidVNC.AbstractInputHandler#handlerDescription() + */ + @Override + public CharSequence getHandlerDescription() { + return getResources().getText(R.string.input_mode_mouse); + } + + /* + * (non-Javadoc) + * + * @see android.androidVNC.AbstractInputHandler#getName() + */ + @Override + public String getName() { + return "MOUSE"; + } + } + + /** + * Touch screen controls, clicks the mouse. DPad pans the screen + * + * @author Michael A. MacDonald + * + */ + class DPadPanTouchMouseMode implements AbstractInputHandler { + + private boolean isPanning; + + /* + * (non-Javadoc) + * + * @see android.androidVNC.AbstractInputHandler#onKeyDown(int, + * android.view.KeyEvent) + */ + @Override + public boolean onKeyDown(int keyCode, KeyEvent evt) { + int xv = 0; + int yv = 0; + boolean result = true; + switch (keyCode) { + case KeyEvent.KEYCODE_DPAD_LEFT: + // xv = -1; + vncCanvas.sendMetaKey(MetaKeyBean.keyArrowLeft); + return result; + // break; + case KeyEvent.KEYCODE_DPAD_RIGHT: + // xv = 1; + vncCanvas.sendMetaKey(MetaKeyBean.keyArrowRight); + return result; + // break; + case KeyEvent.KEYCODE_DPAD_UP: + // yv = -1; + vncCanvas.sendMetaKey(MetaKeyBean.keyArrowUp); + return result; + // break; + case KeyEvent.KEYCODE_DPAD_DOWN: + // yv = 1; + vncCanvas.sendMetaKey(MetaKeyBean.keyArrowDown); + return result; + // break; + default: + result = defaultKeyDownHandler(keyCode, evt); + break; + } + if ((xv != 0 || yv != 0) && !isPanning) { + final int x = xv; + final int y = yv; + isPanning = true; + panner.start(x, y, new Panner.VelocityUpdater() { + + /* + * (non-Javadoc) + * + * @see + * android.androidVNC.Panner.VelocityUpdater#updateVelocity + * (android.graphics.Point, long) + */ + @Override + public boolean updateVelocity(PointF p, long interval) { + double scale = (2.0 * (double) interval / 50.0); + if (Math.abs(p.x) < 500) { + p.x += (int) (scale * x); + } + if (Math.abs(p.y) < 500) { + p.y += (int) (scale * y); + } + return true; + } + }); + vncCanvas.pan(x, y); + } + return result; + } + + /* + * (non-Javadoc) + * + * @see android.androidVNC.AbstractInputHandler#onKeyUp(int, + * android.view.KeyEvent) + */ + @Override + public boolean onKeyUp(int keyCode, KeyEvent evt) { + boolean result = false; + + switch (keyCode) { + case KeyEvent.KEYCODE_DPAD_LEFT: + case KeyEvent.KEYCODE_DPAD_RIGHT: + case KeyEvent.KEYCODE_DPAD_UP: + case KeyEvent.KEYCODE_DPAD_DOWN: + panner.stop(); + isPanning = false; + result = true; + break; + default: + result = defaultKeyUpHandler(keyCode, evt); + break; + } + return result; + } + + /* + * (non-Javadoc) + * + * @see + * android.androidVNC.AbstractInputHandler#onTouchEvent(android.view + * .MotionEvent) + */ + @Override + public boolean onTouchEvent(MotionEvent event) { + // Mouse Pointer Control Mode + // Pointer event is absolute coordinates. + + // MK + if (event.getAction() == MotionEvent.ACTION_CANCEL) + return true; + + vncCanvas.changeTouchCoordinatesToFullFrame(event); + if (vncCanvas.processPointerEvent(event, true)) { + return true; + } + return VncCanvasActivity.super.onTouchEvent(event); + } + + /* + * (non-Javadoc) + * + * @see + * android.androidVNC.AbstractInputHandler#onTrackballEvent(android. + * view.MotionEvent) + */ + @Override + public boolean onTrackballEvent(MotionEvent evt) { + return false; + } + + /* + * (non-Javadoc) + * + * @see android.androidVNC.AbstractInputHandler#handlerDescription() + */ + @Override + public CharSequence getHandlerDescription() { + return getResources().getText(R.string.input_mode_dpad_pan_touchpad_mouse); + } + + /* + * (non-Javadoc) + * + * @see android.androidVNC.AbstractInputHandler#getName() + */ + @Override + public String getName() { + return "DPAD_PAN_TOUCH_MOUSE"; + } + } + + public void onConnected() { + + } +} diff --git a/app/src/main/java/android/androidVNC/VncConstants.java b/app/src/main/java/android/androidVNC/VncConstants.java new file mode 100644 index 0000000..7aaa22b --- /dev/null +++ b/app/src/main/java/android/androidVNC/VncConstants.java @@ -0,0 +1,8 @@ +package android.androidVNC; + +/** + * Keys for intent values + */ +public class VncConstants { + public static final String CONNECTION = "android.androidVNC.CONNECTION"; +} diff --git a/app/src/main/java/android/androidVNC/ZlibInStream.java b/app/src/main/java/android/androidVNC/ZlibInStream.java new file mode 100644 index 0000000..91103a1 --- /dev/null +++ b/app/src/main/java/android/androidVNC/ZlibInStream.java @@ -0,0 +1,112 @@ +package android.androidVNC; +/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved. + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +// +// A ZlibInStream reads from a zlib.io.InputStream +// + +public class ZlibInStream extends InStream { + + static final int defaultBufSize = 16384; + + public ZlibInStream(int bufSize_) { + bufSize = bufSize_; + b = new byte[bufSize]; + ptr = end = ptrOffset = 0; + inflater = new java.util.zip.Inflater(); + } + + public ZlibInStream() { this(defaultBufSize); } + + public void setUnderlying(InStream is, int bytesIn_) { + underlying = is; + bytesIn = bytesIn_; + ptr = end = 0; + } + + public void reset() throws Exception { + ptr = end = 0; + if (underlying == null) return; + + while (bytesIn > 0) { + decompress(); + end = 0; // throw away any data + } + underlying = null; + } + + public int pos() { return ptrOffset + ptr; } + + protected int overrun(int itemSize, int nItems) throws Exception { + if (itemSize > bufSize) + throw new Exception("ZlibInStream overrun: max itemSize exceeded"); + if (underlying == null) + throw new Exception("ZlibInStream overrun: no underlying stream"); + + if (end - ptr != 0) + System.arraycopy(b, ptr, b, 0, end - ptr); + + ptrOffset += ptr; + end -= ptr; + ptr = 0; + + while (end < itemSize) { + decompress(); + } + + if (itemSize * nItems > end) + nItems = end / itemSize; + + return nItems; + } + + // decompress() calls the decompressor once. Note that this won't + // necessarily generate any output data - it may just consume some input + // data. Returns false if wait is false and we would block on the underlying + // stream. + + private void decompress() throws Exception { + try { + underlying.check(1); + int avail_in = underlying.getend() - underlying.getptr(); + if (avail_in > bytesIn) + avail_in = bytesIn; + + if (inflater.needsInput()) { + inflater.setInput(underlying.getbuf(), underlying.getptr(), avail_in); + } + + int n = inflater.inflate(b, end, bufSize - end); + + end += n; + if (inflater.needsInput()) { + bytesIn -= avail_in; + underlying.setptr(underlying.getptr() + avail_in); + } + } catch (java.util.zip.DataFormatException e) { + throw new Exception("ZlibInStream: inflate failed"); + } + } + + private InStream underlying; + private int bufSize; + private int ptrOffset; + private java.util.zip.Inflater inflater; + private int bytesIn; +} diff --git a/app/src/main/java/android/androidVNC/ZoomScaling.java b/app/src/main/java/android/androidVNC/ZoomScaling.java new file mode 100644 index 0000000..45e39c5 --- /dev/null +++ b/app/src/main/java/android/androidVNC/ZoomScaling.java @@ -0,0 +1,187 @@ +/** + * Copyright (C) 2009 Michael A. MacDonald + */ +package android.androidVNC; + +import android.graphics.Matrix; +import android.widget.ImageView.ScaleType; + +import com.vectras.vm.R; + +/** + * @author Michael A. MacDonald + */ +class ZoomScaling extends AbstractScaling { + + static final String TAG = "ZoomScaling"; + + private Matrix matrix; + int canvasXOffset; + int canvasYOffset; + float scaling; + float minimumScale; + + /** + * @param id + * @param scaleType + */ + public ZoomScaling() { + super(R.id.itemZoomable, ScaleType.MATRIX); + matrix = new Matrix(); + scaling = 1; + } + + /* (non-Javadoc) + * @see android.androidVNC.AbstractScaling#getDefaultHandlerId() + */ + @Override + int getDefaultHandlerId() { + return R.id.itemInputTouchPanZoomMouse; + } + + /* (non-Javadoc) + * @see android.androidVNC.AbstractScaling#isAbleToPan() + */ + @Override + boolean isAbleToPan() { + return true; + } + + /* (non-Javadoc) + * @see android.androidVNC.AbstractScaling#isValidInputMode(int) + */ + @Override + boolean isValidInputMode(int mode) { + return mode != R.id.itemInputFitToScreen; + } + + /** + * Call after scaling and matrix have been changed to resolve scrolling + * @param activity + */ + private void resolveZoom(VncCanvasActivity activity) + { + activity.vncCanvas.scrollToAbsolute(); + activity.vncCanvas.pan(0,0); + } + + /* (non-Javadoc) + * @see android.androidVNC.AbstractScaling#zoomIn(android.androidVNC.VncCanvasActivity) + */ + @Override + void zoomIn(VncCanvasActivity activity) { + resetMatrix(); + standardizeScaling(); + scaling += 0.25; + if (scaling > 4.0) + { + scaling = (float)4.0; + activity.zoomer.setIsZoomInEnabled(false); + } + activity.zoomer.setIsZoomOutEnabled(false); //disable Zoomer + matrix.postScale(scaling, scaling); + //Log.v(TAG,String.format("before set matrix scrollx = %d scrolly = %d", activity.vncCanvas.getScrollX(), activity.vncCanvas.getScrollY())); + activity.vncCanvas.setImageMatrix(matrix); + resolveZoom(activity); + } + + /* (non-Javadoc) + * @see android.androidVNC.AbstractScaling#getScale() + */ + @Override + float getScale() { + return scaling; + } + + /* (non-Javadoc) + * @see android.androidVNC.AbstractScaling#zoomOut(android.androidVNC.VncCanvasActivity) + */ + @Override + void zoomOut(VncCanvasActivity activity) { + resetMatrix(); + standardizeScaling(); + scaling -= 0.25; + if (scaling < minimumScale) + { + scaling = minimumScale; + activity.zoomer.setIsZoomOutEnabled(false); + } + activity.zoomer.setIsZoomInEnabled(true); + matrix.postScale(scaling, scaling); + //Log.v(TAG,String.format("before set matrix scrollx = %d scrolly = %d", activity.vncCanvas.getScrollX(), activity.vncCanvas.getScrollY())); + activity.vncCanvas.setImageMatrix(matrix); + //Log.v(TAG,String.format("after set matrix scrollx = %d scrolly = %d", activity.vncCanvas.getScrollX(), activity.vncCanvas.getScrollY())); + resolveZoom(activity); + } + + /* (non-Javadoc) + * @see android.androidVNC.AbstractScaling#adjust(android.androidVNC.VncCanvasActivity, float, float, float) + */ + @Override + void adjust(VncCanvasActivity activity, float scaleFactor, float fx, + float fy) { + float newScale = scaleFactor * scaling; + if (scaleFactor < 1) + { + if (newScale < minimumScale) + { + newScale = minimumScale; + activity.zoomer.setIsZoomOutEnabled(false); + } + activity.zoomer.setIsZoomInEnabled(true); + } + else + { + if (newScale > 4) + { + newScale = 4; + activity.zoomer.setIsZoomInEnabled(false); + } + activity.zoomer.setIsZoomOutEnabled(true); + } + // ax is the absolute x of the focus + int xPan = activity.vncCanvas.absoluteXPosition; + float ax = (fx / scaling) + xPan; + float newXPan = (scaling * xPan - scaling * ax + newScale * ax)/newScale; + int yPan = activity.vncCanvas.absoluteYPosition; + float ay = (fy / scaling) + yPan; + float newYPan = (scaling * yPan - scaling * ay + newScale * ay)/newScale; + resetMatrix(); + scaling = newScale; + matrix.postScale(scaling, scaling); + activity.vncCanvas.setImageMatrix(matrix); + resolveZoom(activity); + activity.vncCanvas.pan((int)(newXPan - xPan), (int)(newYPan - yPan)); + } + + private void resetMatrix() + { + matrix.reset(); + matrix.preTranslate(canvasXOffset, canvasYOffset); + } + + /** + * Set scaling to one of the clicks on the zoom scale + */ + private void standardizeScaling() + { + scaling = ((float)((int)(scaling * 4))) / 4; + } + + /* (non-Javadoc) + * @see android.androidVNC.AbstractScaling#setScaleTypeForActivity(android.androidVNC.VncCanvasActivity) + */ + @Override + public void setScaleTypeForActivity(VncCanvasActivity activity) { + super.setScaleTypeForActivity(activity); + scaling = (float)1.0; + minimumScale = activity.vncCanvas.bitmapData.getMinimumScale(); + canvasXOffset = -activity.vncCanvas.getCenteredXOffset(); + canvasYOffset = -activity.vncCanvas.getCenteredYOffset(); + resetMatrix(); + activity.vncCanvas.setImageMatrix(matrix); + // Reset the pan position to (0,0) + resolveZoom(activity); + } + +} diff --git a/app/src/main/java/android/androidVNC/androidVNC.java b/app/src/main/java/android/androidVNC/androidVNC.java new file mode 100644 index 0000000..aa7996c --- /dev/null +++ b/app/src/main/java/android/androidVNC/androidVNC.java @@ -0,0 +1,306 @@ +/* + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +// +// androidVNC is the Activity for setting VNC server IP and port. +// + +package android.androidVNC; + +import java.util.ArrayList; + +import android.app.Activity; +import android.app.ActivityManager.MemoryInfo; +import android.app.Dialog; +import android.content.DialogInterface; +import android.content.Intent; +import android.os.Bundle; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.widget.AdapterView; +import android.widget.ArrayAdapter; +import android.widget.Button; +import android.widget.CheckBox; +import android.widget.EditText; +import android.widget.RadioGroup; +import android.widget.Spinner; +import android.widget.TextView; + +import com.vectras.vm.R; + +public class androidVNC extends Activity { + private EditText ipText; + private EditText portText; + private EditText passwordText; + private Button goButton; + private TextView repeaterText; + private RadioGroup groupForceFullScreen; + private Spinner colorSpinner; + private Spinner spinnerConnection; + private ConnectionBean selected; + private EditText textNickname; + private EditText textUsername; + private CheckBox checkboxKeepPassword; + private CheckBox checkboxLocalCursor; + private boolean repeaterTextSet; + + @Override + public void onCreate(Bundle icicle) { + + super.onCreate(icicle); + setContentView(R.layout.main_vnc); + + ipText = (EditText) findViewById(R.id.textIP); + portText = (EditText) findViewById(R.id.textPORT); + passwordText = (EditText) findViewById(R.id.textPASSWORD); + textNickname = (EditText) findViewById(R.id.textNickname); + textUsername = (EditText) findViewById(R.id.textUsername); + goButton = (Button) findViewById(R.id.buttonGO); + ((Button) findViewById(R.id.buttonRepeater)) + .setOnClickListener(new View.OnClickListener() { + + @Override + public void onClick(View v) { + showDialog(R.layout.repeater_dialog); + } + }); + ((Button) findViewById(R.id.buttonImportExport)) + .setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + showDialog(R.layout.importexport); + } + }); + colorSpinner = (Spinner) findViewById(R.id.colorformat); + COLORMODEL[] models = COLORMODEL.values(); + ArrayAdapter colorSpinnerAdapter = new ArrayAdapter( + this, android.R.layout.simple_spinner_item, models); + groupForceFullScreen = (RadioGroup) findViewById(R.id.groupForceFullScreen); + checkboxKeepPassword = (CheckBox) findViewById(R.id.checkboxKeepPassword); + checkboxLocalCursor = (CheckBox) findViewById(R.id.checkboxUseLocalCursor); + colorSpinner.setAdapter(colorSpinnerAdapter); + colorSpinner.setSelection(0); + spinnerConnection = (Spinner) findViewById(R.id.spinnerConnection); + spinnerConnection + .setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { + @Override + public void onItemSelected(AdapterView ad, View view, + int itemIndex, long id) { + selected = (ConnectionBean) ad.getSelectedItem(); + updateViewFromSelected(); + } + + @Override + public void onNothingSelected(AdapterView ad) { + selected = null; + } + }); + spinnerConnection + .setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() { + + /* + * (non-Javadoc) + * + * @see android.widget.AdapterView.OnItemLongClickListener# + * onItemLongClick(android.widget.AdapterView, + * android.view.View, int, long) + */ + @Override + public boolean onItemLongClick(AdapterView arg0, + View arg1, int arg2, long arg3) { + spinnerConnection.setSelection(arg2); + selected = (ConnectionBean) spinnerConnection + .getItemAtPosition(arg2); + canvasStart(); + return true; + } + + }); + repeaterText = (TextView) findViewById(R.id.textRepeaterId); + goButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + canvasStart(); + } + }); + + } + + protected void onDestroy() { + + super.onDestroy(); + } + + /* + * (non-Javadoc) + * + * @see android.app.Activity#onCreateDialog(int) + */ + @Override + protected Dialog onCreateDialog(int id) { + return new RepeaterDialog(this); + } + + /* + * (non-Javadoc) + * + * @see android.app.Activity#onCreateOptionsMenu(android.view.Menu) + */ + @Override + public boolean onCreateOptionsMenu(Menu menu) { + getMenuInflater().inflate(R.menu.androidvncmenu, menu); + return true; + } + + + /* + * (non-Javadoc) + * + * @see android.app.Activity#onOptionsItemSelected(android.view.MenuItem) + */ + @Override + public boolean onOptionsItemSelected(MenuItem item) { + if (item.getItemId() == R.id.itemSaveAsCopy){ + updateSelectedFromView(); + arriveOnPage(); + } else if (item.getItemId() == R.id.itemDeleteConnection || + item.getItemId() == R.id.itemOpenDoc) { + Utils.showDocumentation(this); + } + return true; + } + + private void updateViewFromSelected() { + if (selected == null) + return; + ipText.setText(selected.getAddress()); + portText.setText(Integer.toString(selected.getPort())); + if (selected.getPassword().length() > 0) { + passwordText.setText(selected.getPassword()); + } + groupForceFullScreen + .check(selected.getForceFull() == BitmapImplHint.AUTO ? R.id.radioForceFullScreenAuto + : (selected.getForceFull() == BitmapImplHint.FULL ? R.id.radioForceFullScreenOn + : R.id.radioForceFullScreenOff)); + checkboxLocalCursor.setChecked(selected.getUseLocalCursor()); + textNickname.setText(selected.getNickname()); + COLORMODEL cm = COLORMODEL.valueOf(selected.getColorModel()); + COLORMODEL[] colors = COLORMODEL.values(); + for (int i = 0; i < colors.length; ++i) { + if (colors[i] == cm) { + colorSpinner.setSelection(i); + break; + } + } + } + + /** + * Called when changing view to match selected connection or from Repeater + * dialog to update the repeater information shown. + * + * @param repeaterId + * If null or empty, show text for not using repeater + */ + void updateRepeaterInfo(boolean useRepeater, String repeaterId) { + if (useRepeater) { + repeaterText.setText(repeaterId); + repeaterTextSet = true; + } else { + repeaterText.setText(getText(R.string.repeater_empty_text)); + repeaterTextSet = false; + } + } + + private void updateSelectedFromView() { + if (selected == null) { + return; + } + selected.setAddress(ipText.getText().toString()); + try { + selected.setPort(Integer.parseInt(portText.getText().toString())); + } catch (NumberFormatException nfe) { + + } + selected.setNickname(textNickname.getText().toString()); + + selected.setForceFull(groupForceFullScreen.getCheckedRadioButtonId() == R.id.radioForceFullScreenAuto ? BitmapImplHint.AUTO + : (groupForceFullScreen.getCheckedRadioButtonId() == R.id.radioForceFullScreenOn ? BitmapImplHint.FULL + : BitmapImplHint.TILE)); + selected.setPassword(passwordText.getText().toString()); + + selected.setUseLocalCursor(checkboxLocalCursor.isChecked()); + selected.setColorModel(((COLORMODEL) colorSpinner.getSelectedItem()) + .nameString()); + } + + protected void onStart() { + super.onStart(); + arriveOnPage(); + } + + void arriveOnPage() { + ArrayList connections = new ArrayList(); + connections.add(0, new ConnectionBean()); + int connectionIndex = 0; + + spinnerConnection.setAdapter(new ArrayAdapter(this, + android.R.layout.simple_spinner_item, connections + .toArray(new ConnectionBean[connections.size()]))); + spinnerConnection.setSelection(connectionIndex, false); + selected = connections.get(connectionIndex); + updateViewFromSelected(); + } + + protected void onStop() { + super.onStop(); + if (selected == null) { + return; + } + updateSelectedFromView(); + + } + + + + private void canvasStart() { + if (selected == null) + return; + MemoryInfo info = Utils.getMemoryInfo(this); + if (info.lowMemory) { + // Low Memory situation. Prompt. + Utils.showYesNoPrompt( + this, + "Continue?", + "Android reports low system memory.\nContinue with VNC connection?", + new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + vnc(); + } + }, null); + } else + vnc(); + } + + private void vnc() { + updateSelectedFromView(); + Intent intent = new Intent(this, VncCanvasActivity.class); + startActivity(intent); + } + +} diff --git a/app/src/main/java/com/antlersoft/android/bc/BCActivityManagerDefault.java b/app/src/main/java/com/antlersoft/android/bc/BCActivityManagerDefault.java new file mode 100644 index 0000000..a5d9b60 --- /dev/null +++ b/app/src/main/java/com/antlersoft/android/bc/BCActivityManagerDefault.java @@ -0,0 +1,21 @@ +/** + * Copyright (C) 2009 Michael A. MacDonald + */ +package com.antlersoft.android.bc; + +import android.app.ActivityManager; + +/** + * @author Michael A. MacDonald + */ +class BCActivityManagerDefault implements IBCActivityManager { + + /* (non-Javadoc) + * @see com.antlersoft.android.bc.IBCActivityManager#getMemoryClass(android.app.ActivityManager) + */ + @Override + public int getMemoryClass(ActivityManager am) { + return 16; + } + +} diff --git a/app/src/main/java/com/antlersoft/android/bc/BCActivityManagerV5.java b/app/src/main/java/com/antlersoft/android/bc/BCActivityManagerV5.java new file mode 100644 index 0000000..a764c76 --- /dev/null +++ b/app/src/main/java/com/antlersoft/android/bc/BCActivityManagerV5.java @@ -0,0 +1,21 @@ +/** + * Copyright (C) 2009 Michael A. MacDonald + */ +package com.antlersoft.android.bc; + +import android.app.ActivityManager; + +/** + * @author Michael A. MacDonald + */ +public class BCActivityManagerV5 implements IBCActivityManager { + + /* (non-Javadoc) + * @see com.antlersoft.android.bc.IBCActivityManager#getMemoryClass(android.app.ActivityManager) + */ + @Override + public int getMemoryClass(ActivityManager am) { + return am.getMemoryClass(); + } + +} diff --git a/app/src/main/java/com/antlersoft/android/bc/BCFactory.java b/app/src/main/java/com/antlersoft/android/bc/BCFactory.java new file mode 100644 index 0000000..d9cf102 --- /dev/null +++ b/app/src/main/java/com/antlersoft/android/bc/BCFactory.java @@ -0,0 +1,191 @@ +/** + * Copyright (C) 2009 Michael A. MacDonald + */ +package com.antlersoft.android.bc; + +/** + * Create interface implementations appropriate to the current version of the SDK; + * implementations can allow use of higher-level SDK calls in .apk's that will still run + * on lower-level SDK's + * @author Michael A. MacDonald + */ +public class BCFactory { + + private static BCFactory _theInstance = new BCFactory(); + + private IBCActivityManager bcActivityManager; + private IBCHaptic bcHaptic; + private IBCMotionEvent bcMotionEvent; + private IBCStorageContext bcStorageContext; + + /** + * This is here so checking the static doesn't get optimized away; + * note we can't use SDK_INT because that is too new + * @return sdk version + */ + int getSdkVersion() + { + try + { + return android.os.Build.VERSION.SDK_INT; + } + catch (NumberFormatException nfe) + { + return 1; + } + } + + /** + * Return the implementation of IBCActivityManager appropriate for this SDK level + * @return + */ + public IBCActivityManager getBCActivityManager() + { + if (bcActivityManager == null) + { + synchronized (this) + { + if (bcActivityManager == null) + { + if (getSdkVersion() >= 5) + { + try + { + bcActivityManager = (IBCActivityManager)getClass().getClassLoader().loadClass("com.antlersoft.android.bc.BCActivityManagerV5").newInstance(); + } + catch (Exception ie) + { + bcActivityManager = new BCActivityManagerDefault(); + throw new RuntimeException("Error instantiating", ie); + } + } + else + { + bcActivityManager = new BCActivityManagerDefault(); + } + } + } + } + return bcActivityManager; + } + + + + /** + * Return the implementation of IBCHaptic appropriate for this SDK level + * + * Since we dropped support of SDK levels prior to 3, there is only one version at the moment. + * @return + */ + public IBCHaptic getBCHaptic() + { + if (bcHaptic == null) + { + synchronized (this) + { + if (bcHaptic == null) + { + try + { + bcHaptic = (IBCHaptic)getClass().getClassLoader().loadClass("com.antlersoft.android.bc.BCHapticDefault").newInstance(); + } + catch (Exception ie) + { + throw new RuntimeException("Error instantiating", ie); + } + } + } + } + return bcHaptic; + } + + /** + * Return the implementation of IBCMotionEvent appropriate for this SDK level + * @return + */ + public IBCMotionEvent getBCMotionEvent() + { + if (bcMotionEvent == null) + { + synchronized (this) + { + if (bcMotionEvent == null) + { + if (getSdkVersion() >= 5) + { + try + { + bcMotionEvent = (IBCMotionEvent)getClass().getClassLoader().loadClass("com.antlersoft.android.bc.BCMotionEvent5").newInstance(); + } + catch (Exception ie) + { + throw new RuntimeException("Error instantiating", ie); + } + } + else + { + try + { + bcMotionEvent = (IBCMotionEvent)getClass().getClassLoader().loadClass("com.antlersoft.android.bc.BCMotionEvent4").newInstance(); + } + catch (Exception ie) + { + throw new RuntimeException("Error instantiating", ie); + } + } + } + } + } + return bcMotionEvent; + } + + /** + * + * @return An implementation of IBCStorageContext appropriate for the running Android release + */ + public IBCStorageContext getStorageContext() + { + if (bcStorageContext == null) + { + synchronized (this) + { + if (bcStorageContext == null) + { + if (getSdkVersion() >= 8) + { + try + { + bcStorageContext = (IBCStorageContext)getClass().getClassLoader().loadClass("com.antlersoft.android.bc.BCStorageContext8").newInstance(); + } + catch (Exception ie) + { + throw new RuntimeException("Error instantiating", ie); + } + } + else + { + try + { + bcStorageContext = (IBCStorageContext)getClass().getClassLoader().loadClass("com.antlersoft.android.bc.BCStorageContext7").newInstance(); + } + catch (Exception ie) + { + throw new RuntimeException("Error instantiating", ie); + } + } + } + } + } + return bcStorageContext; + } + + /** + * Returns the only instance of this class, which manages the SDK specific interface + * implementations + * @return Factory instance + */ + public static BCFactory getInstance() + { + return _theInstance; + } +} diff --git a/app/src/main/java/com/antlersoft/android/bc/BCHapticDefault.java b/app/src/main/java/com/antlersoft/android/bc/BCHapticDefault.java new file mode 100644 index 0000000..c632c05 --- /dev/null +++ b/app/src/main/java/com/antlersoft/android/bc/BCHapticDefault.java @@ -0,0 +1,33 @@ +/** + * Copyright (C) 2009 Michael A. MacDonald + */ +package com.antlersoft.android.bc; + +import android.view.View; +import android.view.HapticFeedbackConstants; + +/** + * Implementation for SDK version >= 3 + * @author Michael A. MacDonald + */ +class BCHapticDefault implements IBCHaptic { + + /* (non-Javadoc) + * @see com.antlersoft.android.bc.IBCHaptic#performLongPressHaptic(android.view.View) + */ + @Override + public boolean performLongPressHaptic(View v) { + return v.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS,HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING|HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING + ); + } + + /* (non-Javadoc) + * @see com.antlersoft.android.bc.IBCHaptic#setIsHapticEnabled(android.view.View, boolean) + */ +/* + * @Override + public boolean setIsHapticEnabled(View v, boolean enabled) { + return v.setHapticFeedbackEnabled(hapticFeedbackEnabled) + } +*/ +} diff --git a/app/src/main/java/com/antlersoft/android/bc/BCMotionEvent4.java b/app/src/main/java/com/antlersoft/android/bc/BCMotionEvent4.java new file mode 100644 index 0000000..9e7eab2 --- /dev/null +++ b/app/src/main/java/com/antlersoft/android/bc/BCMotionEvent4.java @@ -0,0 +1,24 @@ +/** + * Copyright (c) 2010 Michael A. MacDonald + */ +package com.antlersoft.android.bc; + +import android.view.MotionEvent; + +/** + * Pre-sdk 5 version; add fake multi-touch sensing later? + * + * @author Michael A. MacDonald + * + */ +class BCMotionEvent4 implements IBCMotionEvent { + + /* (non-Javadoc) + * @see com.antlersoft.android.bc.IBCMotionEvent#getPointerCount(android.view.MotionEvent) + */ + @Override + public int getPointerCount(MotionEvent evt) { + return 1; + } + +} diff --git a/app/src/main/java/com/antlersoft/android/bc/BCMotionEvent5.java b/app/src/main/java/com/antlersoft/android/bc/BCMotionEvent5.java new file mode 100644 index 0000000..af15236 --- /dev/null +++ b/app/src/main/java/com/antlersoft/android/bc/BCMotionEvent5.java @@ -0,0 +1,22 @@ +/** + * Copyright (c) 2010 Michael A. MacDonald + */ +package com.antlersoft.android.bc; + +import android.view.MotionEvent; + +/** + * @author Michael A. MacDonald + * + */ +class BCMotionEvent5 implements IBCMotionEvent { + + /* (non-Javadoc) + * @see com.antlersoft.android.bc.IBCMotionEvent#getPointerCount(android.view.MotionEvent) + */ + @Override + public int getPointerCount(MotionEvent evt) { + return evt.getPointerCount(); + } + +} diff --git a/app/src/main/java/com/antlersoft/android/bc/BCStorageContext7.java b/app/src/main/java/com/antlersoft/android/bc/BCStorageContext7.java new file mode 100644 index 0000000..2758783 --- /dev/null +++ b/app/src/main/java/com/antlersoft/android/bc/BCStorageContext7.java @@ -0,0 +1,31 @@ +/** + * Copyright (c) 2011 Michael A. MacDonald + */ +package com.antlersoft.android.bc; + +import java.io.File; + +import android.content.Context; + +import android.os.Environment; + +/** + * @author Michael A. MacDonald + * + */ +public class BCStorageContext7 implements IBCStorageContext { + + /* (non-Javadoc) + * @see com.antlersoft.android.bc.IBCStorageContext#getExternalStorageDir(android.content.Context, java.lang.String) + */ + @Override + public File getExternalStorageDir(Context context, String type) { + File f = Environment.getExternalStorageDirectory(); + f = new File(f, "Android/data/android.androidVNC/files"); + if (type != null) + f=new File(f, type); + f.mkdirs(); + return f; + } + +} diff --git a/app/src/main/java/com/antlersoft/android/bc/BCStorageContext8.java b/app/src/main/java/com/antlersoft/android/bc/BCStorageContext8.java new file mode 100644 index 0000000..3a7988f --- /dev/null +++ b/app/src/main/java/com/antlersoft/android/bc/BCStorageContext8.java @@ -0,0 +1,24 @@ +/** + * Copyright (c) 2010 Michael A. MacDonald + */ +package com.antlersoft.android.bc; + +import java.io.File; + +import android.content.Context; + +/** + * @author Michael A. MacDonald + * + */ +class BCStorageContext8 implements IBCStorageContext { + + /* (non-Javadoc) + * @see com.antlersoft.android.bc.IBCStorageContext#getExternalStorageDir(android.content.Context, java.lang.String) + */ + @Override + public File getExternalStorageDir(Context context, String type) { + return context.getExternalFilesDir(type); + } + +} diff --git a/app/src/main/java/com/antlersoft/android/bc/IBCActivityManager.java b/app/src/main/java/com/antlersoft/android/bc/IBCActivityManager.java new file mode 100644 index 0000000..103c19e --- /dev/null +++ b/app/src/main/java/com/antlersoft/android/bc/IBCActivityManager.java @@ -0,0 +1,13 @@ +/** + * Copyright (C) 2009 Michael A. MacDonald + */ +package com.antlersoft.android.bc; + +import android.app.ActivityManager; + +/** + * @author Michael A. MacDonald + */ +public interface IBCActivityManager { + public int getMemoryClass(ActivityManager am); +} diff --git a/app/src/main/java/com/antlersoft/android/bc/IBCHaptic.java b/app/src/main/java/com/antlersoft/android/bc/IBCHaptic.java new file mode 100644 index 0000000..4a53f7c --- /dev/null +++ b/app/src/main/java/com/antlersoft/android/bc/IBCHaptic.java @@ -0,0 +1,20 @@ +/** + * Copyright (C) 2009 Michael A. MacDonald + */ +package com.antlersoft.android.bc; + +import android.view.View; + +/** + * Access the Haptic interfaces added in version 3 without breaking compatibility + * @author Michael A. MacDonald + */ +public interface IBCHaptic { + public boolean performLongPressHaptic(View v); + /** + * Set whether haptic feedback is enabled on the view + * @param enabled + * @return Old value of setting + */ + //public boolean setIsHapticEnabled(View v, boolean enabled); +} diff --git a/app/src/main/java/com/antlersoft/android/bc/IBCMotionEvent.java b/app/src/main/java/com/antlersoft/android/bc/IBCMotionEvent.java new file mode 100644 index 0000000..166f23a --- /dev/null +++ b/app/src/main/java/com/antlersoft/android/bc/IBCMotionEvent.java @@ -0,0 +1,24 @@ +/** + * Copyright (c) 2010 Michael A. MacDonald + */ +package com.antlersoft.android.bc; + +import android.view.MotionEvent; + +/** + * Access to SDK-dependent features of MotionEvent + * + * @see android.view.MotionEvent + * + * @author Michael A. MacDonald + * + */ +public interface IBCMotionEvent { + /** + * Obtain the number of pointers active in the event + * @see android.view.MotionEvent#getPointerCount() + * @param evt + * @return number of pointers + */ + int getPointerCount(MotionEvent evt); +} diff --git a/app/src/main/java/com/antlersoft/android/bc/IBCStorageContext.java b/app/src/main/java/com/antlersoft/android/bc/IBCStorageContext.java new file mode 100644 index 0000000..69d6ab6 --- /dev/null +++ b/app/src/main/java/com/antlersoft/android/bc/IBCStorageContext.java @@ -0,0 +1,26 @@ +/** + * Copyright (c) 2010 Michael A. MacDonald + */ +package com.antlersoft.android.bc; + +import android.content.Context; + +import java.io.File; + +/** + * Provides a way to access the directory on external storage as returned by + * Context.getExternal... added in API 8 that will work with earlier API releases. + * @author Michael A. MacDonald + * + */ +public interface IBCStorageContext { + /** + * + * @param context Context within the application with which the storage will be associated + * @param type May be null; if specified, references a sub-directory within the base directory + * for the app in the external storage + * @return File representing abstract path of storage directory; refer to android.os.Environment to + * see if the path is actually accessible + */ + public File getExternalStorageDir(Context context, String type); +} diff --git a/app/src/main/java/com/antlersoft/android/drawing/OverlappingCopy.java b/app/src/main/java/com/antlersoft/android/drawing/OverlappingCopy.java new file mode 100644 index 0000000..96e15fa --- /dev/null +++ b/app/src/main/java/com/antlersoft/android/drawing/OverlappingCopy.java @@ -0,0 +1,136 @@ +package com.antlersoft.android.drawing; + +import com.antlersoft.util.ObjectPool; +import com.antlersoft.util.SafeObjectPool; + +import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.graphics.Rect; + +public class OverlappingCopy +{ + private static SafeObjectPool ocRectPool = new SafeObjectPool() { + @Override + protected Rect itemForPool() + { + return new Rect(); + } + }; + private static void transformRect(Rect source, Rect transformedSource, int deltaX, int deltaY) + { + transformedSource.set(deltaX < 0 ? source.right * -1 : source.left, + deltaY < 0 ? source.bottom * -1 : source.top, + deltaX < 0 ? source.left * -1 : source.right, + deltaY < 0 ? source.top * -1 : source.bottom); + } + private static void copyTransformedRect(Rect stepSourceRect, Rect stepDestRect, int deltaX, int deltaY, Bitmap data, Canvas bitmapBackedCanvas, Paint paint) + { + transformRect(stepSourceRect,stepSourceRect,deltaX,deltaY); + stepDestRect.set(stepSourceRect); + stepDestRect.offset(deltaX,deltaY); + bitmapBackedCanvas.drawBitmap(data, stepSourceRect, stepDestRect, paint); + } + public static void Copy(Bitmap data, Canvas bitmapBackedCanvas, Paint paint, Rect source, int destX, int destY) + { + Copy(data,bitmapBackedCanvas,paint,source,destX,destY,ocRectPool); + } + public static void Copy(Bitmap data, Canvas bitmapBackedCanvas, Paint paint, Rect source, int destX, int destY, ObjectPool rectPool) + { + //android.util.Log.i("LBM","Copy "+source.toString()+" to "+destX+","+destY); + int deltaX = destX - source.left; + int deltaY = destY - source.top; + int absDeltaX = deltaX < 0 ? -deltaX : deltaX; + int absDeltaY = deltaY < 0 ? -deltaY : deltaY; + + // Look for degenerate case + if (absDeltaX == 0 && absDeltaY == 0) + return; + // Look for non-overlap case + if (absDeltaX >= source.right - source.left || absDeltaY >= source.bottom - source.top) + { + // Non-overlapping copy + ObjectPool.Entry entry = rectPool.reserve(); + Rect dest = entry.get(); + dest.set(source.left + deltaX, source.top + deltaY, source.right + deltaX, source.bottom + deltaY); + bitmapBackedCanvas.drawBitmap(data, source, dest, paint); + rectPool.release(entry); + return; + } + // Determine coordinate transform so that dest rectangle is always down and to the right. + ObjectPool.Entry transformedSourceEntry = rectPool.reserve(); + Rect transformedSource = transformedSourceEntry.get(); + transformRect(source,transformedSource,deltaX,deltaY); + ObjectPool.Entry transformedDestEntry = rectPool.reserve(); + Rect transformedDest = transformedDestEntry.get(); + transformedDest.set(transformedSource); + transformedDest.offset(absDeltaX, absDeltaY); + ObjectPool.Entry intersectEntry = rectPool.reserve(); + Rect intersect = intersectEntry.get(); + intersect.setIntersect(transformedSource, transformedDest); + + boolean xStepDone = false; + int xStepWidth; + int yStepHeight; + if (absDeltaX > absDeltaY) + { + xStepWidth = absDeltaX; + yStepHeight = source.bottom - source.top - absDeltaY; + } + else + { + xStepWidth = source.right - source.left - absDeltaX; + yStepHeight = absDeltaY; + } + + ObjectPool.Entry stepSourceEntry = rectPool.reserve(); + Rect stepSourceRect = stepSourceEntry.get(); + ObjectPool.Entry stepDestEntry = rectPool.reserve(); + Rect stepDestRect = stepDestEntry.get(); + + for (int xStep = 0; ! xStepDone; xStep++) + { + int stepRight = intersect.right - xStep * xStepWidth; + int stepLeft = stepRight - xStepWidth; + if (stepLeft <= intersect.left) + { + stepLeft = intersect.left; + xStepDone = true; + } + boolean yStepDone = false; + for (int yStep = 0; ! yStepDone; yStep++) + { + int stepBottom = intersect.bottom - yStep * yStepHeight; + int stepTop = stepBottom - yStepHeight; + if (stepTop <= intersect.top) + { + stepTop = intersect.top; + yStepDone = true; + } + stepSourceRect.set(stepLeft,stepTop,stepRight,stepBottom); + //android.util.Log.i("LBM","Copy transformed "+stepSourceRect.toString()+" "+deltaX+" "+deltaY); + copyTransformedRect(stepSourceRect, stepDestRect, deltaX, deltaY, data, bitmapBackedCanvas, paint); + } + } + if (absDeltaX>0) + { + // Copy left edge + stepSourceRect.set(transformedSource.left,transformedSource.top,intersect.left,transformedSource.bottom); + copyTransformedRect(stepSourceRect, stepDestRect, deltaX, deltaY, data, bitmapBackedCanvas, paint); + } + if (absDeltaY>0) + { + // Copy top excluding left edge + stepSourceRect.set(intersect.left,transformedSource.top,transformedSource.right,intersect.top); + copyTransformedRect(stepSourceRect, stepDestRect, deltaX, deltaY, data, bitmapBackedCanvas, paint); + } + + rectPool.release(stepDestEntry); + rectPool.release(stepSourceEntry); + rectPool.release(intersectEntry); + rectPool.release(transformedDestEntry); + rectPool.release(transformedSourceEntry); + } +} + + diff --git a/app/src/main/java/com/antlersoft/android/drawing/RectList.java b/app/src/main/java/com/antlersoft/android/drawing/RectList.java new file mode 100644 index 0000000..c1de320 --- /dev/null +++ b/app/src/main/java/com/antlersoft/android/drawing/RectList.java @@ -0,0 +1,550 @@ +/** + * Copyright (C) 2009 Michael A. MacDonald + */ +package com.antlersoft.android.drawing; + +import android.graphics.Rect; + +import java.util.ArrayList; + +import com.antlersoft.util.ObjectPool; + +/** + * A list of rectangular regions that together represent an area of interest. Provides + * a set of operations that apply to the whole area, adding, changing and mutating the + * rectangles in the list as required. + *

+ * Invariants: None of the rectangles in the list overlap; no pair of rectangles in the list + * together make a single rectangle (none share a complete side) + *

+ *

+ * Instances of this class are not thread safe + *

+ * @author Michael A. MacDonald + * + */ +public class RectList { + + enum OverlapType { + NONE, + SAME, + CONTAINS, + CONTAINED_BY, + COALESCIBLE, + PARTIAL + } + + static final int LEFT = 1; + static final int TOP_LEFT = 2; + static final int TOP = 4; + static final int TOP_RIGHT = 8; + static final int RIGHT = 16; + static final int BOTTOM_RIGHT = 32; + static final int BOTTOM = 64; + static final int BOTTOM_LEFT = 128; + + /** + * The part left over when one rectangle is subtracted from another + * @author Michael A. MacDonald + * + */ + static class NonOverlappingPortion + { + Rect leftPortion; + Rect topLeftPortion; + Rect topPortion; + Rect topRightPortion; + Rect rightPortion; + Rect bottomRightPortion; + Rect bottomPortion; + Rect bottomLeftPortion; + + int r1Owns; + int r2Owns; + int common; + int adjacent; + boolean horizontalOverlap; + boolean verticalOverlap; + + Rect coalesced; + + NonOverlappingPortion() + { + leftPortion = new Rect(); + topLeftPortion = new Rect(); + topPortion = new Rect(); + topRightPortion = new Rect(); + rightPortion = new Rect(); + bottomRightPortion = new Rect(); + bottomPortion = new Rect(); + bottomLeftPortion = new Rect(); + coalesced = new Rect(); + } + + void setCornerOwnership(int side1, int side2, int corner) + { + int combined = (side1 | side2); + if ((r1Owns & combined) == combined) + r1Owns |= corner; + else if ((r2Owns & combined) == combined) + r2Owns |= corner; + } + + void setCornerOwnership() + { + setCornerOwnership(LEFT,TOP,TOP_LEFT); + setCornerOwnership(TOP,RIGHT,TOP_RIGHT); + setCornerOwnership(BOTTOM,RIGHT,BOTTOM_RIGHT); + setCornerOwnership(BOTTOM,LEFT,BOTTOM_LEFT); + } + + /** + * Populates with the borders remaining when r2 is subtracted from r1 + * @param r1 + * @param r2 + * @return + */ + OverlapType overlap(Rect r1, Rect r2) + { + r1Owns = 0; + r2Owns = 0; + common = 0; + adjacent = 0; + OverlapType result = OverlapType.NONE; + horizontalOverlap = false; + verticalOverlap = false; + + if (r1.left < r2.left) + { + leftPortion.left = topLeftPortion.left = bottomLeftPortion.left = r1.left; + if (r2.left < r1.right) { + leftPortion.right = topLeftPortion.right = bottomLeftPortion.right = topPortion.left = bottomPortion.left = r2.left; + horizontalOverlap = true; + } else { + leftPortion.right = topLeftPortion.right = bottomLeftPortion.right = topPortion.left = bottomPortion.left = r1.right; + if (r2.left == r1.right) + adjacent |= LEFT; + } + r1Owns |= LEFT; + } + else + { + leftPortion.left = topLeftPortion.left = bottomLeftPortion.left = r2.left; + if (r1.left < r2.right) { + leftPortion.right = topLeftPortion.right = bottomLeftPortion.right = topPortion.left = bottomPortion.left = r1.left; + horizontalOverlap = true; + } else { + leftPortion.right = topLeftPortion.right = bottomLeftPortion.right = topPortion.left = bottomPortion.left = r2.right; + if ( r1.left == r2.right) + adjacent |= RIGHT; + } + if (r2.left < r1.left) + r2Owns |= LEFT; + else + common |= LEFT; + } + if (r1.top < r2.top) + { + topPortion.top = topLeftPortion.top = topRightPortion.top = r1.top; + if (r2.top < r1.bottom) { + topPortion.bottom = topLeftPortion.bottom = topRightPortion.bottom = leftPortion.top = rightPortion.top = r2.top; + verticalOverlap = true; + } else { + topPortion.bottom = topLeftPortion.bottom = topRightPortion.bottom = leftPortion.top = rightPortion.top = r1.bottom; + if (r2.top == r1.bottom) + adjacent |= TOP; + } + r1Owns |= TOP; + } + else + { + topPortion.top = topLeftPortion.top = topRightPortion.top = r2.top; + if (r1.top < r2.bottom) { + topPortion.bottom = topLeftPortion.bottom = topRightPortion.bottom = leftPortion.top = rightPortion.top = r1.top; + verticalOverlap = true; + } else { + topPortion.bottom = topLeftPortion.bottom = topRightPortion.bottom = leftPortion.top = rightPortion.top = r2.bottom; + if (r1.top == r2.bottom) + adjacent |= BOTTOM; + } + if (r2.top < r1.top) + r2Owns |= TOP; + else + common |= TOP; + } + if (r1.right > r2.right) + { + rightPortion.right = topRightPortion.right = bottomRightPortion.right = r1.right; + if (r2.right > r1.left) { + rightPortion.left = topRightPortion.left = bottomRightPortion.left = topPortion.right = bottomPortion.right = r2.right; + horizontalOverlap = true; + } else { + rightPortion.left = topRightPortion.left = bottomRightPortion.left = topPortion.right = bottomPortion.right = r1.left; + if (r2.right == r1.left) + adjacent |= RIGHT; + } + r1Owns |= RIGHT; + } + else + { + rightPortion.right = topRightPortion.right = bottomRightPortion.right = r2.right; + if (r1.right > r2.left) { + rightPortion.left = topRightPortion.left = bottomRightPortion.left = topPortion.right = bottomPortion.right = r1.right; + horizontalOverlap = true; + } else { + rightPortion.left = topRightPortion.left = bottomRightPortion.left = topPortion.right = bottomPortion.right = r2.left; + if (r1.right==r2.left) + adjacent |= LEFT; + } + if (r2.right > r1.right) + r2Owns |= RIGHT; + else + common |= RIGHT; + } + if (r1.bottom > r2.bottom) + { + bottomPortion.bottom = bottomLeftPortion.bottom = bottomRightPortion.bottom = r1.bottom; + if (r2.bottom > r1.top) { + bottomPortion.top = bottomLeftPortion.top = bottomRightPortion.top = leftPortion.bottom = rightPortion.bottom = r2.bottom; + verticalOverlap = true; + } else { + bottomPortion.top = bottomLeftPortion.top = bottomRightPortion.top = leftPortion.bottom = rightPortion.bottom = r1.top; + if (r2.bottom==r1.top) + adjacent |= BOTTOM; + } + r1Owns |= BOTTOM; + } + else + { + bottomPortion.bottom = bottomLeftPortion.bottom = bottomRightPortion.bottom = r2.bottom; + if (r1.bottom > r2.top) { + bottomPortion.top = bottomLeftPortion.top = bottomRightPortion.top = leftPortion.bottom = rightPortion.bottom = r1.bottom; + verticalOverlap = true; + } else { + bottomPortion.top = bottomLeftPortion.top = bottomRightPortion.top = leftPortion.bottom = rightPortion.bottom = r2.top; + if (r1.bottom==r2.top) + adjacent |= TOP; + } + if (r2.bottom > r1.bottom) + r2Owns |= BOTTOM; + else + common |= BOTTOM; + } + if ( common == (LEFT|RIGHT|TOP|BOTTOM)) + { + result = OverlapType.SAME; + } + else if ((common & (LEFT|RIGHT)) == (LEFT | RIGHT) && (verticalOverlap || (adjacent & (TOP | BOTTOM)) != 0)) + { + result = OverlapType.COALESCIBLE; + coalesced.left = r1.left; + coalesced.right = r1.right; + coalesced.top = topPortion.top; + coalesced.bottom = bottomPortion.bottom; + } + else if ((common & (TOP | BOTTOM)) == (TOP | BOTTOM) && (horizontalOverlap || (adjacent & (LEFT | RIGHT)) != 0)) + { + result = OverlapType.COALESCIBLE; + coalesced.left = leftPortion.left; + coalesced.right = rightPortion.right; + coalesced.top = r1.top; + coalesced.bottom = r1.bottom; + } + else if (verticalOverlap && horizontalOverlap) { + if (r2Owns == 0) + { + result = OverlapType.CONTAINED_BY; + } + else if (r1Owns == 0) + { + result = OverlapType.CONTAINS; + } + else + { + // Partial overlap, non coalescible case + result = OverlapType.PARTIAL; + setCornerOwnership(); + } + } + return result; + } + } + + /** + * Up to 8 Rect objects + * @author Michael A. MacDonald + * + */ + static class NonOverlappingRects + { + ObjectPool.Entry[] rectEntries; + int count; + static final int MAX_RECTS = 8; + + @SuppressWarnings("unchecked") + NonOverlappingRects() + { + rectEntries = new ObjectPool.Entry[MAX_RECTS]; + } + + private void addOwnedRect(int owner, int direction, ObjectPool pool, Rect r) + { + if ((owner & direction)==direction) + { + ObjectPool.Entry entry = pool.reserve(); + rectEntries[count++] = entry; + entry.get().set(r); + } + } + + void Populate(NonOverlappingPortion p, ObjectPool pool, int owner) + { + count = 0; + for (int i=0; i> list; + private ObjectPool pool; + private ObjectPool nonOverlappingRectsPool = new ObjectPool() { + + /* (non-Javadoc) + * @see com.antlersoft.util.ObjectPool#itemForPool() + */ + @Override + protected NonOverlappingRects itemForPool() { + return new NonOverlappingRects(); + } + + }; + private ObjectPool>> listRectsPool = new ObjectPool>>() { + + /* (non-Javadoc) + * @see com.antlersoft.util.ObjectPool#itemForPool() + */ + @Override + protected ArrayList> itemForPool() { + return new ArrayList>(NonOverlappingRects.MAX_RECTS); + } + }; + private NonOverlappingPortion nonOverlappingPortion; + + public RectList(ObjectPool pool) + { + this.pool = pool; + list = new ArrayList>(); + nonOverlappingPortion = new NonOverlappingPortion(); + } + + public int getSize() + { + return list.size(); + } + + public Rect get(int i) + { + return list.get(i).get(); + } + + /** + * Remove all rectangles from the list and release them from the pool + */ + public void clear() + { + for (int i=list.size()-1; i>=0; i--) + { + ObjectPool.Entry r = list.get(i); + pool.release(r); + } + list.clear(); + } + + private void recursiveAdd(ObjectPool.Entry toAdd, int level) + { + if (level>=list.size()) + { + list.add(toAdd); + return; + } + Rect addRect = toAdd.get(); + ObjectPool.Entry thisEntry = list.get(level); + Rect thisRect = thisEntry.get(); + switch (nonOverlappingPortion.overlap(thisRect, addRect)) + { + case NONE : + recursiveAdd(toAdd,level + 1); + break; + case SAME : + case CONTAINS : + pool.release(toAdd); + break; + case CONTAINED_BY : + pool.release(thisEntry); + list.remove(level); + recursiveAdd(toAdd,level); + break; + case COALESCIBLE : + pool.release(thisEntry); + list.remove(level); + addRect.set(nonOverlappingPortion.coalesced); + recursiveAdd(toAdd,0); + break; + case PARTIAL : + pool.release(toAdd); + ObjectPool.Entry rectsEntry = nonOverlappingRectsPool.reserve(); + NonOverlappingRects rects = rectsEntry.get(); + rects.Populate(nonOverlappingPortion,pool,nonOverlappingPortion.r2Owns); + for (int i=0; i entry = pool.reserve(); + Rect r = entry.get(); + r.set(toAdd); + recursiveAdd(entry,0); + } + + /** + * Change the rectangle of interest to include only those portions + * that fall inside bounds. + * @param bounds + */ + public void intersect(Rect bounds) + { + int size = list.size(); + ObjectPool.Entry>> listEntry = listRectsPool.reserve(); + ArrayList> newList = listEntry.get(); + newList.clear(); + for (int i=0; i entry = list.get(i); + Rect rect = entry.get(); + if (rect.intersect(bounds)) + { + newList.add(entry); + } + else + pool.release(entry); + } + list.clear(); + size = newList.size(); + for (int i=0; i>> listEntry = listRectsPool.reserve(); + ArrayList> newList = listEntry.get(); + newList.clear(); + for (int i=0; i entry = list.get(i); + Rect rect = entry.get(); + switch (nonOverlappingPortion.overlap(rect, toSubtract)) + { + case SAME: + pool.release(entry); + newList.clear(); + list.remove(i); + return; + case CONTAINED_BY: + pool.release(entry); + list.remove(i); + i--; + size--; + break; + case NONE: + break; + case COALESCIBLE: + if (!nonOverlappingPortion.verticalOverlap || ! nonOverlappingPortion.horizontalOverlap) + break; + case CONTAINS : + nonOverlappingPortion.setCornerOwnership(); + case PARTIAL : + { + ObjectPool.Entry rectsEntry = nonOverlappingRectsPool.reserve(); + NonOverlappingRects rects = rectsEntry.get(); + rects.Populate(nonOverlappingPortion, pool, nonOverlappingPortion.r1Owns); + pool.release(entry); + list.remove(i); + i--; + size--; + for (int j=0; j m_max_size) + { + m_max_size = Math.max(2 * m_max_size, new_size); + byte[] new_buffer = new byte[m_max_size]; + System.arraycopy(m_buffer, 0, new_buffer, 0, result); + m_buffer = new_buffer; + } + + return result; + } + + public void release() + { + if (m_depth<1) + { + throw new IllegalStateException("release() without reserve()"); + } + m_depth--; + } +} diff --git a/app/src/main/java/com/antlersoft/util/ObjectPool.java b/app/src/main/java/com/antlersoft/util/ObjectPool.java new file mode 100644 index 0000000..e504309 --- /dev/null +++ b/app/src/main/java/com/antlersoft/util/ObjectPool.java @@ -0,0 +1,58 @@ +/** + * Copyright (C) 2009 Michael A. MacDonald + */ +package com.antlersoft.util; + +/** + * A pool of reusable object of a given type. You get the object from a Entry, which you get + * by calling reserve(). When you are done with the object, you call release() passing the Entry. + *

+ * Failing to call release() does not leak memory--but you will not get the benefits + * of reusing the object. You will run into contention issues if you + * call release() while still holding a reference to the pool object. + * @author Michael A. MacDonald + * + */ +public abstract class ObjectPool { + public static class Entry { + S item; + Entry nextEntry; + + Entry(S i, Entry n) + { + item = i; + nextEntry = n; + } + + public S get() { + return item; + } + } + + private Entry next; + public ObjectPool() + { + next = null; + } + + public Entry reserve() + { + if (next == null) + { + next = new Entry(itemForPool(), null); + } + Entry result = next; + next = result.nextEntry; + result.nextEntry = null; + + return result; + } + + public void release(Entry entry) + { + entry.nextEntry = next; + next = entry; + } + + protected abstract R itemForPool(); +} diff --git a/app/src/main/java/com/antlersoft/util/SafeObjectPool.java b/app/src/main/java/com/antlersoft/util/SafeObjectPool.java new file mode 100644 index 0000000..3d197ab --- /dev/null +++ b/app/src/main/java/com/antlersoft/util/SafeObjectPool.java @@ -0,0 +1,29 @@ +/** + * Copyright (C) 2009 Michael A. MacDonald + */ +package com.antlersoft.util; + +/** + * Synchronized object pool + * @author Michael A. MacDonald + * + */ +public abstract class SafeObjectPool extends ObjectPool { + + /* (non-Javadoc) + * @see com.antlersoft.util.ObjectPool#release(com.antlersoft.util.ObjectPool.Entry) + */ + @Override + public synchronized void release(com.antlersoft.util.ObjectPool.Entry entry) { + super.release(entry); + } + + /* (non-Javadoc) + * @see com.antlersoft.util.ObjectPool#reserve() + */ + @Override + public synchronized com.antlersoft.util.ObjectPool.Entry reserve() { + return super.reserve(); + } + +} diff --git a/app/src/main/java/com/vectras/qemu/Config.java b/app/src/main/java/com/vectras/qemu/Config.java new file mode 100644 index 0000000..eb755a3 --- /dev/null +++ b/app/src/main/java/com/vectras/qemu/Config.java @@ -0,0 +1,185 @@ +/* +Copyright (C) Max Kastanas 2012 + + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package com.vectras.qemu; + +import android.androidVNC.COLORMODEL; +import android.androidVNC.VncCanvasActivity; +import android.content.Context; +import android.graphics.Bitmap; +import android.os.Environment; +import android.widget.ImageView.ScaleType; + +import com.vectras.vm.AppConfig; + +import java.util.Hashtable; +import java.util.LinkedHashMap; + +/** + * + * @author dev + */ +public class Config { + + // Constants + public static final int UI_VNC = 0; + public static final int UI_SDL = 1; + public static final int UI_SPICE = 2; + public static final int SDL_MOUSE_LEFT = 1; + public static final int SDL_MOUSE_MIDDLE = 2; + public static final int SDL_MOUSE_RIGHT = 3; + public static final int VNC_REQUEST_CODE = 1004; + public static final int VNC_RESET_RESULT_CODE = 1006; + public static final int SDL_REQUEST_CODE = 1007; + public static final String ACTION_START = "com.vectras.qemu.action.STARTVM"; + + // GUI Options + public static final boolean enable_SDL = true; + public static final boolean enable_SPICE = false; + + public static final boolean enable_qemu_fullScreen = true; + + // App config + public static final String APP_NAME = "Vectras Emulator"; + public static String storagedir = null; + + //Some OSes don't like emulated multi cores for QEMU 2.9.1 you can disable here + /// thought there is also the Disable TSC feature so you don't have to do it here + public static boolean enableSMPOnlyOnKVM = false; + + //set to true if you need to debug native library loading + public static boolean loadNativeLibsEarly = false; + + //XXX: QEMU 3.1.0 needs the libraries to be loaded from the main thread + public static boolean loadNativeLibsMainThread = true; + + public static String wakeLockTag = "vectras:wakelock"; + public static String wifiLockTag = "vectras:wifilock"; + + //this will be populated later + public static String cacheDir = null; + + //we disable mouse modes for now + public static boolean disableMouseModes = true; + + //double tap an hold is still buggy so we keep using the old-way trackpad + public static boolean enableDragOnLongPress = true; + + //we need to define the configuration for the VNC client since we replaced some deprecated + // functions + public static Bitmap.Config bitmapConfig = Bitmap.Config.RGB_565; + + //XXX set scaling to linear it's a tad slower but it's worth it + public static int SDLHintScale=1; + public static boolean viewLogInternally = true; + + + //XXX some archs don't support floppy or sd card + public static boolean enableEmulatedFloppy = true; + public static boolean enableEmulatedSDCard; + public static String destLogFilename = "vectraslog.txt"; + + public static String notificationChannelID = "vectras"; + public static String notificationChannelName = "vectras"; + public static boolean showToast = false; + public static boolean closeFileDescriptors = true; + public static String hda_path; + public static String extra_params; + + + public static final String getCacheDir(){ + return cacheDir.toString(); + } + public static final String getBasefileDir() { + return getCacheDir() + "/vectras/"; + } + + public static String getTmpFolder() { + return getBasefileDir() + "var/tmp"; // Do not modify + } + public static String machineFolder = "machines/"; + public static String getMachineDir(){ + return getBasefileDir() + machineFolder; + } + public static String logFilePath = null; + + + public static final String defaultDNSServer = "8.8.8.8"; + public static String state_filename = "vm.state"; + + //QMP + public static String QMPServer = "127.0.0.1"; + public static int QMPPort = 4444; + + public static int MAX_DISPLAY_REFRESH_RATE = 100; //Hz + + // VNC Defaults + public static String defaultVNCHost = "127.0.0.1"; + public static final String defaultVNCUsername = "vectras"; + public static final String defaultVNCPasswd = ""; + + //It seems that for new veersion of qemu it expectes a relative number + // so we stop using absolute port numbers + public static final int defaultVNCPort = 1; + + public static final String defaultVNCColorMode = COLORMODEL.C24bit.nameString(); + public static final ScaleType defaultFullscreenScaleMode = ScaleType.FIT_CENTER; + public static final ScaleType defaultScaleModeCenter = ScaleType.CENTER; + public static final String defaultInputMode = VncCanvasActivity.TOUCH_ZOOM_MODE; + + //Keyboard Layout + public static String defaultKeyboardLayout = "en-us"; + + + public static boolean enableToggleKeyboard = false; + // Debug + public static final boolean debug = false; + public static boolean debugQmp = false; + + //remove in production + public static boolean debugStrictMode = false; + + public static boolean processMouseHistoricalEvents = false; + + public static String getLocalQMPSocketPath() { + return Config.getCacheDir()+"/qmpsocket"; + } + + public static String getLocalVNCSocketPath() { + return Config.getCacheDir()+"/vncsocket"; + } + + public static enum MouseMode { + Trackpad, External + } + public static MouseMode mouseMode = MouseMode.Trackpad; + + //specify hd interface, alternative we don't need it right now + public static boolean enable_hd_if = false; + public static String hd_if_type = "ide"; + + //Change to true in prod if you want to be notified by default for new versions + public static boolean defaultCheckNewVersion = true; + + public static final String sharedFolder = AppConfig.sharedFolder; + + public static String machinename = "VECTRAS"; + public static int paused = 0; + public static String ui = "VNC"; + public static boolean maxPriority = false; +} diff --git a/app/src/main/java/com/vectras/qemu/MainActivityCommon.java b/app/src/main/java/com/vectras/qemu/MainActivityCommon.java new file mode 100644 index 0000000..83e400e --- /dev/null +++ b/app/src/main/java/com/vectras/qemu/MainActivityCommon.java @@ -0,0 +1,676 @@ +package com.vectras.qemu; + +import android.androidVNC.RfbProto; +import android.androidVNC.VncCanvas; +import android.app.Activity; +import android.app.NotificationManager; +import android.app.ProgressDialog; +import android.content.Context; +import android.content.DialogInterface; +import android.content.Intent; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; +import android.net.Uri; +import android.os.AsyncTask; +import android.os.Environment; +import android.os.Handler; +import android.os.Looper; +import android.os.StrictMode; +import android.util.Log; +import android.view.KeyEvent; +import android.view.View; +import android.widget.EditText; +import android.widget.TextView; + +import androidx.appcompat.app.AlertDialog; +import androidx.appcompat.app.AppCompatActivity; + +import com.vectras.qemu.jni.StartVM; +import com.vectras.qemu.utils.FileInstaller; +import com.vectras.qemu.utils.FileUtils; +import com.vectras.qemu.utils.Machine; +import com.vectras.qemu.utils.QmpClient; +import com.vectras.vm.R; +import com.vectras.vm.utils.UIUtils; + +import java.io.File; +import java.net.InetAddress; +import java.net.NetworkInterface; +import java.net.SocketException; +import java.util.Enumeration; +import java.util.logging.Level; +import java.util.logging.Logger; + +public class MainActivityCommon { + + public static VMStatus currStatus = VMStatus.Ready; + public static boolean vmStarted = false; + public static StartVM vmexecutor; + public static String vnc_passwd = "vectras"; + public static int vnc_allow_external = 1; + public static int qmp_allow_external = 0; + public static ProgressDialog progDialog; + public static View parent; + public static InstallerTask installerTaskTask; + public static boolean timeQuit = false; + public static Object lockTime = new Object(); + + public static final String TAG = "VECTRAS"; + + public static AppCompatActivity activity = null; + + public static boolean libLoaded; + + + static public void onInstall(boolean force) { + FileInstaller.installFiles(activity, force); + } + + public static String getVnc_passwd() { + return vnc_passwd; + } + + public static void setVnc_passwd(String vnc_passwd) { + vnc_passwd = vnc_passwd; + } + + public static String getLocalIpAddress() { + try { + for (Enumeration en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements(); ) { + NetworkInterface intf = en.nextElement(); + for (Enumeration enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements(); ) { + InetAddress inetAddress = enumIpAddr.nextElement(); + if (!inetAddress.isLoopbackAddress() && inetAddress.getHostAddress().toString().contains(".")) { + return inetAddress.getHostAddress().toString(); + } + } + } + } catch (SocketException ex) { + ex.printStackTrace(); + } + return null; + } + + // Start calling the JNI interface + public static void startvm(Activity activity, int UI) { + QmpClient.allow_external = (qmp_allow_external == 1); + vmexecutor.qmp_allow_external = qmp_allow_external; + + if (UI == Config.UI_VNC) { + // disable sound card with VNC + vmexecutor.enablevnc = 1; + vmexecutor.enablespice = 0; + vmexecutor.sound_card = null; + vmexecutor.vnc_allow_external = vnc_allow_external; + RfbProto.allow_external = (vnc_allow_external == 1); + vmexecutor.vnc_passwd = vnc_passwd; + } else if (UI == Config.UI_SDL) { + vmexecutor.enablevnc = 0; + vmexecutor.enablespice = 0; + } else if (UI == Config.UI_SPICE) { + vmexecutor.vnc_allow_external = vnc_allow_external; + vmexecutor.vnc_passwd = vnc_passwd; + vmexecutor.enablevnc = 0; + vmexecutor.enablespice = 1; + } + vmexecutor.startvm(activity, UI); + + } + + + public static void cleanup() { + + vmStarted = false; + + //XXX flush and close all file descriptors if we haven't already + FileUtils.close_fds(); + + ////XXX; we wait till fds flush and close + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + //set the exit code + MainSettingsManager.setExitCode(activity, 1); + + //XXX: SDL seems to lock the keyboard events + // unless we finish the starting activity + activity.finish(); + + Log.v(TAG, "Exit"); + //XXX: We exit here to force unload the native libs + System.exit(0); + + + } + + public static void changeStatus(final VMStatus status_changed) { + activity.runOnUiThread(new Runnable() { + @Override + public void run() { + if (status_changed == VMStatus.Running) { + + vmStarted = true; + } else if (status_changed == VMStatus.Ready || status_changed == VMStatus.Stopped) { + + } else if (status_changed == VMStatus.Saving) { + + } else if (status_changed == VMStatus.Paused) { + + } + } + }); + + } + + public static void install(boolean force) { + progDialog = ProgressDialog.show(activity, "Please Wait", "Installing BIOS...", true); + installerTaskTask = new InstallerTask(); + installerTaskTask.force = force; + installerTaskTask.execute(); + } + + public static void checkAndLoadLibs() { + if (Config.loadNativeLibsEarly) + if (Config.loadNativeLibsMainThread) + setupNativeLibs(); + else + setupNativeLibsAsync(); + } + + public static void clearNotifications() { + NotificationManager notificationManager = (NotificationManager) activity.getApplicationContext().getSystemService(Context.NOTIFICATION_SERVICE); + notificationManager.cancelAll(); + } + + public static void setupNativeLibsAsync() { + + Thread thread = new Thread(new Runnable() { + public void run() { + setupNativeLibs(); + } + }); + thread.setPriority(Thread.MIN_PRIORITY); + thread.start(); + + } + + public static void savePendingEditText() { + View currentView = activity.getCurrentFocus(); + if (currentView != null && currentView instanceof EditText) { + ((EditText) currentView).setFocusable(false); + } + } + + public static void checkLog() { + + Thread t = new Thread(new Runnable() { + public void run() { + + if (MainSettingsManager.getExitCode(activity) != 1) { + MainSettingsManager.setExitCode(activity, 1); + activity.runOnUiThread(new Runnable() { + @Override + public void run() { + UIUtils.promptShowLog(activity); + } + }); + } + } + }); + t.start(); + } + + public static void setupFolders() { + Thread t = new Thread(new Runnable() { + public void run() { + + Config.cacheDir = activity.getCacheDir().getAbsolutePath(); + Config.storagedir = Environment.getExternalStorageDirectory().toString(); + + // Create Temp folder + File folder = new File(Config.getTmpFolder()); + if (!folder.exists()) + folder.mkdirs(); + + + } + }); + t.start(); + } + + //XXX: sometimes this needs to be called from the main thread otherwise + // qemu crashes when it is started later + public static void setupNativeLibs() { + + if (libLoaded) + return; + + //Some devices need stl loaded upfront + //System.loadLibrary("stlport_shared"); + + //Compatibility lib + System.loadLibrary("compat-vectras"); + + //Glib deps + System.loadLibrary("compat-musl"); + + + //Glib + System.loadLibrary("glib-2.0"); + + //Pixman for qemu + System.loadLibrary("pixman-1"); + + //Spice server + if (Config.enable_SPICE) { + System.loadLibrary("crypto"); + System.loadLibrary("ssl"); + System.loadLibrary("spice"); + } + + // //Load SDL library + if (Config.enable_SDL) { + System.loadLibrary("SDL2"); + } + + System.loadLibrary("compat-SDL2-ext"); + + //Vectras needed for vmexecutor + System.loadLibrary("vectras"); + + loadQEMULib(); + + libLoaded = true; + } + + public static void loadQEMULib() { + + try { + System.loadLibrary("qemu-system-i386"); + } catch (Error ex) { + System.loadLibrary("qemu-system-x86_64"); + } + + } + + + public static void setupStrictMode() { + + if (Config.debugStrictMode) { + StrictMode.setThreadPolicy( + new StrictMode.ThreadPolicy.Builder().detectDiskReads().detectDiskWrites().detectNetwork() + //.penaltyDeath() + .penaltyLog().build()); + StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder().detectLeakedSqlLiteObjects() + .detectLeakedClosableObjects().penaltyLog() + // .penaltyDeath() + .build()); + } + + } + + public static void onLicense() { + PackageInfo pInfo = null; + + try { + pInfo = activity.getPackageManager().getPackageInfo(activity.getClass().getPackage().getName(), PackageManager.GET_META_DATA); + } catch (PackageManager.NameNotFoundException e) { + e.printStackTrace(); + return; + } + + final PackageInfo finalPInfo = pInfo; + activity.runOnUiThread(new Runnable() { + @Override + public void run() { + + } + }); + + } + + // Main event function + // Retrives values from saved preferences + public static void onStartButton() { + if (MainService.isRunning) { + startvnc(); + } else { + if (vmexecutor == null) { + + try { + vmexecutor = new StartVM(activity); + } catch (Exception ex) { + UIUtils.toastLong(activity, "Error: " + ex); + return; + + } + } + // dns + vmexecutor.dns_addr = Config.defaultDNSServer; + + vmexecutor.paused = 0; + + if (!vmStarted) { + UIUtils.toastShort(activity, "Starting VM"); + //XXX: make sure that bios files are installed in case we ran out of space in the last + // run + FileInstaller.installFiles(activity, false); + } else { + UIUtils.toastShort(activity, "Connecting to VM"); + } + + if (Config.ui.equals("VNC")) { + vmexecutor.enableqmp = 1; // We enable qemu monitor + startVNC(); + + } else if (Config.ui.equals("SDL")) { + vmexecutor.enableqmp = 0; // We disable qemu monitor + startSDL(); + } else { + vmexecutor.enableqmp = 1; // We enable qemu monitor + startSPICE(); + } + } + } + + public static String getLanguageCode(int index) { + // TODO: Add more languages from /assets/roms/keymaps + switch (index) { + case 0: + return "en-us"; + case 1: + return "es"; + case 2: + return "fr"; + } + return null; + } + + public static void startSDL() { + + Thread tsdl = new Thread(new Runnable() { + public void run() { + startsdl(); + } + }); + if (Config.maxPriority) + tsdl.setPriority(Thread.MAX_PRIORITY); + tsdl.start(); + } + + public static void startVNC() { + + VncCanvas.retries = 0; + if (!vmStarted) { + + Thread tvm = new Thread(new Runnable() { + public void run() { + startvm(activity, Config.UI_VNC); + } + }); + if (Config.maxPriority) + tvm.setPriority(Thread.MAX_PRIORITY); + tvm.start(); + } else { + startvnc(); + } + + + } + + public static void startSPICE() { + + if (!vmStarted) { + + Thread tvm = new Thread(new Runnable() { + public void run() { + startvm(activity, Config.UI_SPICE); + } + }); + if (Config.maxPriority) + tvm.setPriority(Thread.MAX_PRIORITY); + tvm.start(); + } + + } + + public static void onStopButton(boolean exit) { + stopVM(exit); + } + + public static void onRestartButton() { + + execTimer(); + + Machine.resetVM(activity); + } + + public static void onResumeButton() { + + // TODO: This probably has no effect + Thread t = new Thread(new Runnable() { + public void run() { + resumevm(); + } + }); + t.start(); + } + + public static void toggleVisibility(View view) { + if (view.getVisibility() == View.VISIBLE) { + view.setVisibility(View.GONE); + } else if (view.getVisibility() == View.GONE || view.getVisibility() == View.INVISIBLE) { + view.setVisibility(View.VISIBLE); + } + } + + public static boolean onKeyDown(int keyCode, KeyEvent event) { + + if (keyCode == KeyEvent.KEYCODE_BACK) { + activity.moveTaskToBack(true); + return true; // return + } + + return false; + } + + + public static void startvnc() { + + // Wait till Qemu settles + try { + Thread.sleep(2000); + } catch (InterruptedException ex) { + Logger.getLogger(activity.getClass().getName()).log(Level.SEVERE, null, ex); + } + if (MainSettingsManager.getVncExternal(activity)) { + + } else { + connectLocally(); + } + } + + public static void promptConnectLocally(final Activity activity) { + + new Handler(Looper.getMainLooper()).postDelayed(new Runnable() { + @Override + public void run() { + final AlertDialog alertDialog; + alertDialog = new AlertDialog.Builder(activity, R.style.MainDialogTheme).create(); + alertDialog.setTitle("VNC Started"); + TextView stateView = new TextView(activity); + stateView.setText("VNC Server started: " + getLocalIpAddress() + ":" + Config.defaultVNCPort + "\n" + + "Warning: VNC Connection is Unencrypted and not secure make sure you're on a private network!\n"); + + stateView.setPadding(20, 20, 20, 20); + alertDialog.setView(stateView); + + alertDialog.setButton(DialogInterface.BUTTON_POSITIVE, "OK", new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int which) { + alertDialog.dismiss(); + } + }); + alertDialog.setButton(DialogInterface.BUTTON_NEUTRAL, "Connect Locally", new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int which) { + connectLocally(); + } + }); + alertDialog.show(); + } + }, 100); + + + } + + public static void connectLocally() { + //UIUtils.toastShort(MainActivity.this, "Connecting to VM Display"); + Intent intent = getVNCIntent(); + activity.startActivityForResult(intent, Config.VNC_REQUEST_CODE); + } + + public static void startsdl() { + + Intent intent = null; + + intent = new Intent(activity, MainSDLActivity.class); + + android.content.ContentValues values = new android.content.ContentValues(); + activity.startActivityForResult(intent, Config.SDL_REQUEST_CODE); + } + + + public static void resumevm() { + if (vmexecutor != null) { + vmexecutor.resumevm(); + UIUtils.toastShort(activity, "VM Reset"); + } else { + + UIUtils.toastShort(activity, "VM not running"); + } + + } + + public static Intent getVNCIntent() { + return new Intent(activity, com.vectras.qemu.MainVNCActivity.class); + + } + + + public static void goToSettings() { + Intent i = new Intent(activity, MainSettingsManager.class); + activity.startActivity(i); + } + + public static void onViewLog() { + + Thread t = new Thread(new Runnable() { + public void run() { + FileUtils.viewVectrasLog(activity); + } + }); + t.start(); + } + + public static void goToURL(String url) { + + Intent i = new Intent(Intent.ACTION_VIEW); + i.setData(Uri.parse(url)); + activity.startActivity(i); + + } + + public static void stopVM(boolean exit) { + execTimer(); + Machine.stopVM(activity); + } + + public static void stopTimeListener() { + + synchronized (lockTime) { + timeQuit = true; + lockTime.notifyAll(); + } + } + + + public static void timer() { + //XXX: No timers just ping a few times + for (int i = 0; i < 3; i++) { + checkAndUpdateStatus(false); + + try { + Thread.sleep(1000); + } catch (InterruptedException ex) { + ex.printStackTrace(); + } + } + + } + + public static void checkAndUpdateStatus(boolean force) { + if (vmexecutor != null) { + VMStatus status = checkStatus(); + if (force || status != currStatus) { + currStatus = status; + changeStatus(status); + } + } + } + + public static void execTimer() { + + Thread t = new Thread(new Runnable() { + public void run() { + startTimer(); + } + }); + t.start(); + } + + public static void startTimer() { + stopTimeListener(); + + timeQuit = false; + try { + timer(); + } catch (Exception ex) { + ex.printStackTrace(); + + } + + } + + + public static enum VMStatus { + Ready, Stopped, Saving, Paused, Completed, Failed, Unknown, Running + } + + public static VMStatus checkStatus() { + VMStatus state = VMStatus.Ready; + if (vmexecutor != null && libLoaded && vmexecutor.get_state().toUpperCase().equals("RUNNING")) { + state = VMStatus.Running; + } + return state; + } + + public static class InstallerTask extends AsyncTask { + public boolean force; + + @Override + protected Void doInBackground(Void... arg0) { + onInstall(force); + if (progDialog.isShowing()) { + progDialog.dismiss(); + } + return null; + } + + @Override + protected void onPostExecute(Void test) { + + } + } + +} diff --git a/app/src/main/java/com/vectras/qemu/MainApplication.java b/app/src/main/java/com/vectras/qemu/MainApplication.java new file mode 100644 index 0000000..bcf9d1a --- /dev/null +++ b/app/src/main/java/com/vectras/qemu/MainApplication.java @@ -0,0 +1,20 @@ +package com.vectras.qemu; + +import android.app.Application; + +public class MainApplication extends Application { + + @Override + public void onCreate() { + super.onCreate(); + try { + Class.forName("android.os.AsyncTask"); + } catch (Throwable ignore) { + // ignored + } + + + + } + +} diff --git a/app/src/main/java/com/vectras/qemu/MainSDLActivity.java b/app/src/main/java/com/vectras/qemu/MainSDLActivity.java new file mode 100644 index 0000000..1a25ff9 --- /dev/null +++ b/app/src/main/java/com/vectras/qemu/MainSDLActivity.java @@ -0,0 +1,1856 @@ +package com.vectras.qemu; + +import android.app.Activity; +import android.app.AlertDialog; +import android.app.Dialog; +import android.app.ProgressDialog; +import android.content.Context; +import android.content.DialogInterface; +import android.content.pm.ActivityInfo; +import android.content.res.Configuration; +import android.media.AudioManager; +import android.os.AsyncTask; +import android.os.Bundle; +import android.os.Handler; +import android.os.Looper; +import android.os.Vibrator; +import android.util.Log; +import android.view.GestureDetector; +import android.view.Gravity; +import android.view.InputDevice; +import android.view.KeyCharacterMap; +import android.view.KeyEvent; +import android.view.MotionEvent; +import android.view.View; +import android.view.ViewGroup; +import android.view.WindowManager; +import android.widget.Button; +import android.widget.LinearLayout; +import android.widget.RelativeLayout; +import android.widget.ScrollView; +import android.widget.SeekBar; +import android.widget.SeekBar.OnSeekBarChangeListener; +import android.widget.TextView; +import androidx.appcompat.app.ActionBar; + +import com.vectras.qemu.utils.FileUtils; +import com.vectras.qemu.utils.Machine; +import com.vectras.qemu.utils.QmpClient; +import com.vectras.vm.R; +import com.vectras.vm.utils.UIUtils; + +import java.io.File; +import java.util.logging.Level; +import java.util.logging.Logger; +import javax.microedition.khronos.egl.EGLConfig; +import javax.microedition.khronos.egl.EGLContext; +import javax.microedition.khronos.egl.EGLDisplay; +import javax.microedition.khronos.egl.EGLSurface; +import org.json.JSONObject; +import org.libsdl.app.SDLActivity; +import org.libsdl.app.SDLControllerManager; + +/** + * SDL Activity + */ +public class MainSDLActivity extends SDLActivity { + public static final String TAG = "MainSDLActivity"; + + public static MainSDLActivity activity ; + + public static final int KEYBOARD = 10000; + public static final int QUIT = 10001; + public static final int HELP = 10002; + + private boolean monitorMode = false; + private boolean mouseOn = false; + private Object lockTime = new Object(); + private boolean timeQuit = false; + private boolean once = true; + private boolean zoomable = false; + private String status = null; + + public static int vm_width; + public static int vm_height; + + + private Thread timeListenerThread; + + private ProgressDialog progDialog; + protected static ViewGroup mMainLayout; + + public String cd_iso_path = null; + + // HDD + public String hda_img_path = null; + public String hdb_img_path = null; + public String hdc_img_path = null; + public String hdd_img_path = null; + + public String fda_img_path = null; + public String fdb_img_path = null; + public String cpu = null; + + // Default Settings + public int memory = 128; + public String bootdevice = null; + + // net + public String net_cfg = "None"; + public int nic_num = 1; + public String vga_type = "std"; + public String hd_cache = "default"; + public String nic_driver = null; + public String soundcard = null; + public String lib = "libvectras.so"; + public String lib_path = null; + public String snapshot_name = "vectras"; + public int disableacpi = 0; + public int disablehpet = 0; + public int disabletsc = 0; + public int enableqmp = 0; + public int enablevnc = 0; + public String vnc_passwd = null; + public int vnc_allow_external = 0; + public String qemu_dev = null; + public String qemu_dev_value = null; + + public String dns_addr = null; + public int restart = 0; + + // This is what SDL runs in. It invokes SDL_main(), eventually + private static Thread mSDLThread; + + // EGL private objects + private static EGLContext mEGLContext; + private static EGLSurface mEGLSurface; + private static EGLDisplay mEGLDisplay; + private static EGLConfig mEGLConfig; + private static int mGLMajor, mGLMinor; + + + private static Activity activity1; + + // public static void showTextInput(int x, int y, int w, int h) { + // // Transfer the task to the main thread as a Runnable + // // mSingleton.commandHandler.post(new ShowTextInputHandler(x, y, w, h)); + // } + + public static void singleClick(final MotionEvent event, final int pointer_id) { + + Thread t = new Thread(new Runnable() { + public void run() { + // Log.d("SDL", "Mouse Single Click"); + try { + Thread.sleep(50); + } catch (InterruptedException ex) { + // Log.v("singletap", "Could not sleep"); + } + MainActivityCommon.vmexecutor.onVectrasMouse(Config.SDL_MOUSE_LEFT, MotionEvent.ACTION_DOWN, 1,0, 0); + try { + Thread.sleep(50); + } catch (InterruptedException ex) { + // Log.v("singletap", "Could not sleep"); + } + MainActivityCommon.vmexecutor.onVectrasMouse(Config.SDL_MOUSE_LEFT, MotionEvent.ACTION_UP, 1, 0, 0); + } + }); + t.start(); + } + + public static void delayKey(int ms) { + try { + Thread.sleep(ms); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + public static void sendCtrlAltKey(int code) { + delayKey(100); + SDLActivity.onNativeKeyDown(KeyEvent.KEYCODE_CTRL_LEFT); + delayKey(100); + SDLActivity.onNativeKeyDown(KeyEvent.KEYCODE_ALT_LEFT); + delayKey(100); + if(code>=0) { + SDLActivity.onNativeKeyDown(code); + delayKey(100); + SDLActivity.onNativeKeyUp(code); + delayKey(100); + } + SDLActivity.onNativeKeyUp(KeyEvent.KEYCODE_ALT_LEFT); + delayKey(100); + SDLActivity.onNativeKeyUp(KeyEvent.KEYCODE_CTRL_LEFT); + } + + public void stopTimeListener() { + Log.v("SaveVM", "Stopping Listener"); + synchronized (this.lockTime) { + this.timeQuit = true; + this.lockTime.notifyAll(); + } + } + + public void onDestroy() { + + // Now wait for the SDL thread to quit + Log.v("VectrasSDL", "Waiting for SDL thread to quit"); + if (mSDLThread != null) { + try { + mSDLThread.join(); + } catch (Exception e) { + Log.v("SDL", "Problem stopping thread: " + e); + } + mSDLThread = null; + + Log.v("SDL", "Finished waiting for SDL thread"); + } + this.stopTimeListener(); + + MainActivityCommon.vmexecutor.doStopVM(0); + super.onDestroy(); + } + + public void startTimeListener() { + this.stopTimeListener(); + timeQuit = false; + try { + Log.v("Listener", "Time Listener Started..."); + + synchronized (lockTime) { + while (timeQuit == false) { + lockTime.wait(); + } + lockTime.notifyAll(); + } + } catch (Exception ex) { + ex.printStackTrace(); + Log.v("SaveVM", "Time listener thread error: " + ex.getMessage()); + } + Log.v("Listener", "Time listener thread exited..."); + + } + + public static boolean toggleKeyboardFlag = true; + +// @Override +// public boolean onOptionsItemSelected(final MenuItem item) { +// // Log.v("Vectras", "Inside Options Check"); +// super.onOptionsItemSelected(item); +// if (item.getItemId() == R.id.itemReset) { +// Machine.resetVM(activity); +// } else if (item.getItemId() == R.id.itemShutdown) { +// UIUtils.hideKeyboard(this, mSurface); +// Machine.stopVM(activity); +// } else if (item.getItemId() == R.id.itemMouse) { +// onMouseMode(); +// } else if (item.getItemId() == this.KEYBOARD || item.getItemId() == R.id.itemKeyboard) { +// //XXX: need to post after delay to work correctly +// new Handler(Looper.getMainLooper()).postDelayed(new Runnable() { +// @Override +// public void run() { +// toggleKeyboardFlag = UIUtils.onKeyboard(activity, toggleKeyboardFlag, mSurface); +// } +// }, 200); +// +// } +// else if (item.getItemId() == R.id.itemMonitor) { +// if (this.monitorMode) { +// this.onVMConsole(); +// } else { +// this.onMonitor(); +// } +// } else if (item.getItemId() == R.id.itemVolume) { +// this.onSelectMenuVol(); +// } else if (item.getItemId() == R.id.itemSaveState) { +// this.promptPause(activity); +// } else if (item.getItemId() == R.id.itemSaveSnapshot) { +// //TODO: +// //this.promptStateName(activity); +// } else if (item.getItemId() == R.id.itemFitToScreen) { +// onFitToScreen(); +// } else if (item.getItemId() == R.id.itemStretchToScreen) { +// onStretchToScreen(); +// } else if (item.getItemId() == R.id.itemZoomIn) { +// this.setZoomIn(); +// } else if (item.getItemId() == R.id.itemZoomOut) { +// this.setZoomOut(); +// } else if (item.getItemId() == R.id.itemCtrlAltDel) { +// this.onCtrlAltDel(); +// } else if (item.getItemId() == R.id.itemCtrlC) { +// this.onCtrlC(); +// } else if (item.getItemId() == R.id.itemOneToOne) { +// this.onNormalScreen(); +// } else if (item.getItemId() == R.id.itemZoomable) { +// this.setZoomable(); +// } else if (item.getItemId() == this.QUIT) { +// } else if (item.getItemId() == R.id.itemHelp) { +// UIUtils.onHelp(this); +// } else if (item.getItemId() == R.id.itemHideToolbar) { +// this.onHideToolbar(); +// } else if (item.getItemId() == R.id.itemDisplay) { +// this.onSelectMenuSDLDisplay(); +// } else if (item.getItemId() == R.id.itemViewLog) { +// this.onViewLog(); +// } +// // this.canvas.requestFocus(); +// +// +// this.invalidateOptionsMenu(); +// return true; +// } + + public void onViewLog() { + FileUtils.viewVectrasLog(this); + } + + public void onHideToolbar(){ + ActionBar bar = this.getSupportActionBar(); + if (bar != null) { + bar.hide(); + } + } + + + private void onMouseMode() { + + String [] items = {"Trackpad Mouse (Phone)", + "Bluetooth/USB Mouse (Desktop mode)", //Physical mouse for Chromebook, Android x86 PC, or Bluetooth Mouse + }; + final AlertDialog.Builder mBuilder = new AlertDialog.Builder(this); + mBuilder.setTitle("Mouse"); + mBuilder.setSingleChoiceItems(items, Config.mouseMode.ordinal(), new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int i) { + switch(i){ + case 0: + setUIModeMobile(true); + break; + case 1: + promptSetUIModeDesktop(false); + break; + default: + break; + } + dialog.dismiss(); + } + }); + final AlertDialog alertDialog = mBuilder.create(); + alertDialog.show(); + + } + + public boolean checkVMResolutionFits() { + int width = mLayout.getWidth(); + int height = mLayout.getHeight(); + ActionBar bar = activity.getSupportActionBar(); + + if (!MainSettingsManager.getAlwaysShowMenuToolbar(MainSDLActivity.this) + && bar != null && bar.isShowing()) { + height += bar.getHeight(); + } + + if(vm_width < width && vm_height < height) + return true; + + return false; + } + + public void calibration() { + //XXX: No need to calibrate for SDL trackpad. + } + + private void setUIModeMobile(boolean fitToScreen){ + + try { + UIUtils.setOrientation(this); + MotionEvent a = MotionEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, 0, 0, 0); + + //TODO: needed? + //MainSDLActivity.singleClick(a, 0); + Config.mouseMode = Config.MouseMode.Trackpad; + MainSettingsManager.setDesktopMode(this, false); + MainActivityCommon.vmexecutor.setRelativeMouseMode(1); + if(Config.showToast) + UIUtils.toastShort(this.getApplicationContext(), "Trackpad Enabled"); + if(fitToScreen) + onFitToScreen(); + else + onNormalScreen(); + calibration(); + invalidateOptionsMenu(); + }catch (Exception ex){ + if(Config.debug) + ex.printStackTrace(); + } + + } + + private void promptSetUIModeDesktop(final boolean mouseMethodAlt) { + + + final AlertDialog alertDialog; + alertDialog = new AlertDialog.Builder(activity, R.style.MainDialogTheme).create(); + alertDialog.setTitle("Desktop Mode"); + + LinearLayout mLayout = new LinearLayout(this); + mLayout.setPadding(20,20,20,20); + mLayout.setOrientation(LinearLayout.VERTICAL); + + TextView textView = new TextView(activity); + textView.setVisibility(View.VISIBLE); + String desktopInstructions = this.getString(R.string.desktopInstructions); + if(!checkVMResolutionFits()){ + String resolutionWarning = "Warning: Machine resolution " + + vm_width+ "x" + vm_height + + " is too high for Desktop Mode. " + + "Scaling will be used and Mouse Alignment will not be accurate. " + + "Reduce display resolution within the Guest OS for better experience.\n\n"; + desktopInstructions = resolutionWarning + desktopInstructions; + } + textView.setText(desktopInstructions); + + ScrollView scrollView = new ScrollView(this); + scrollView.addView(textView); + + LinearLayout.LayoutParams params = new LinearLayout.LayoutParams( + LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT); + mLayout.addView(scrollView, params); + + alertDialog.setView(mLayout); + + alertDialog.setButton(DialogInterface.BUTTON_POSITIVE, "OK", new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int which) { + setUIModeDesktop(); + alertDialog.dismiss(); + } + }); + alertDialog.setButton(DialogInterface.BUTTON_NEGATIVE, "Cancel", new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int which) { + alertDialog.dismiss(); + } + }); + alertDialog.show(); + + } + + private void setUIModeDesktop() { + + try { + MotionEvent a = MotionEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, 0, 0, 0); + + //TODO: needed? + //MainSDLActivity.singleClick(a, 0); + + //TODO: not needed? + //SDLActivity.onNativeMouseReset(0, 0, MotionEvent.ACTION_MOVE, 0, 0, 0); + //SDLActivity.onNativeMouseReset(0, 0, MotionEvent.ACTION_MOVE, vm_width, vm_height, 0); + + Config.mouseMode = Config.MouseMode.External; + MainSettingsManager.setDesktopMode(this, true); + MainActivityCommon.vmexecutor.setRelativeMouseMode(0); + if(Config.showToast) + UIUtils.toastShort(MainSDLActivity.this, "External Mouse Enabled"); + onNormalScreen(); + calibration(); + invalidateOptionsMenu(); + }catch (Exception ex){ + if(Config.debug) + ex.printStackTrace(); + } + } + + private void onCtrlAltDel() { + + SDLActivity.onNativeKeyDown(KeyEvent.KEYCODE_CTRL_RIGHT); + SDLActivity.onNativeKeyDown(KeyEvent.KEYCODE_ALT_RIGHT); + SDLActivity.onNativeKeyDown(KeyEvent.KEYCODE_FORWARD_DEL); + SDLActivity.onNativeKeyUp(KeyEvent.KEYCODE_FORWARD_DEL); + SDLActivity.onNativeKeyUp(KeyEvent.KEYCODE_ALT_RIGHT); + SDLActivity.onNativeKeyUp(KeyEvent.KEYCODE_CTRL_RIGHT); + } + + private void onCtrlC() { + + SDLActivity.onNativeKeyDown(KeyEvent.KEYCODE_CTRL_RIGHT); + SDLActivity.onNativeKeyDown(KeyEvent.KEYCODE_C); + SDLActivity.onNativeKeyUp(KeyEvent.KEYCODE_C); + SDLActivity.onNativeKeyUp(KeyEvent.KEYCODE_CTRL_RIGHT); + } + + + //TODO: not working + private void onStretchToScreen() { + + + new Thread(new Runnable() { + public void run() { + Log.d(TAG, "onStretchToScreen"); + screenMode = SDLScreenMode.Fullscreen; + sendCtrlAltKey(KeyEvent.KEYCODE_F); // not working + if(Config.showToast) + UIUtils.toastShort(activity, "Resizing, Please Wait"); + resize(null); + + } + }).start(); + + } + + private void onFitToScreen() { + try { + UIUtils.setOrientation(this); + ActionBar bar = MainSDLActivity.this.getSupportActionBar(); + if (bar != null && !MainSettingsManager.getAlwaysShowMenuToolbar(this)) { + bar.hide(); + } + new Thread(new Runnable() { + public void run() { + Log.d(TAG, "onFitToScreen"); + screenMode = SDLScreenMode.FitToScreen; + if(Config.showToast) + UIUtils.toastShort(activity, "Resizing, Please Wait"); + resize(null); + + } + }).start(); + }catch (Exception ex){ + if(Config.debug) + ex.printStackTrace(); + } + + } + + private void onNormalScreen() { + try { + ActionBar bar = MainSDLActivity.this.getSupportActionBar(); + if (bar != null && !MainSettingsManager.getAlwaysShowMenuToolbar(this)) { + bar.hide(); + } + setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE); + new Thread(new Runnable() { + public void run() { + Log.d(TAG, "onNormalScreen"); + screenMode = SDLScreenMode.Normal; + if(Config.showToast) + UIUtils.toastShort(activity, "Resizing, Please Wait"); + resize(null); + + } + }).start(); + }catch (Exception ex){ + if(Config.debug) + ex.printStackTrace(); + } + + } + + public void resize(final Configuration newConfig) { + + //XXX: flag so no mouse events are processed + isResizing = true; + + //XXX: This is needed so Nougat+ devices will update their layout + new Handler(Looper.getMainLooper()).post(new Runnable() { + @Override + public void run() { + ((ExSDLSurface) mSurface).getHolder().setFixedSize(1, 1); + setLayout(newConfig); + + new Handler(Looper.getMainLooper()).postDelayed(new Runnable() { + @Override + public void run() { + //vsdl((VectrasSDLSurface) mSurface).doResize(false, newConfig); + } + }, 1000); + } + }); + + } + + private void setZoomIn() { + + new Thread(new Runnable() { + public void run() { + screenMode = SDLScreenMode.Normal; + sendCtrlAltKey(KeyEvent.KEYCODE_4); + } + }).start(); + + } + + private void setZoomOut() { + + + new Thread(new Runnable() { + public void run() { + screenMode = SDLScreenMode.Normal; + sendCtrlAltKey(KeyEvent.KEYCODE_3); + + } + }).start(); + + } + + private void setZoomable() { + + zoomable = true; + + } + +// @Override +// public boolean onPrepareOptionsMenu(Menu menu) { +// menu.clear(); +// return this.setupMenu(menu); +// } +// +// @Override +// public boolean onCreateOptionsMenu(Menu menu) { +// menu.clear(); +// return this.setupMenu(menu); +// } +// +// public boolean setupMenu(Menu menu) { +// // Log.v("Vectras", "Inside Options Created"); +// getMenuInflater().inflate(R.menu.sdlactivitymenu, menu); +// +// int maxMenuItemsShown = 4; +// int actionShow = MenuItemCompat.SHOW_AS_ACTION_IF_ROOM; +// if(UIUtils.isLandscapeOrientation(this)) { +// maxMenuItemsShown = 6; +// actionShow = MenuItemCompat.SHOW_AS_ACTION_ALWAYS; +// } +// +// // if (vncCanvas.scaling != null) { +// // menu.findItem(vncCanvas.scaling.getId()).setChecked(true); +// // } +// +// // Remove snapshots for now +// menu.removeItem(menu.findItem(R.id.itemSaveSnapshot).getItemId()); +// +// // Remove Monitor console for SDL2 it creates 2 SDL windows and SDL for +// // android supports only 1 +// menu.removeItem(menu.findItem(R.id.itemMonitor).getItemId()); +// +// // Remove scaling for now +// menu.removeItem(menu.findItem(R.id.itemScaling).getItemId()); +// +// // Remove external mouse for now +// menu.removeItem(menu.findItem(R.id.itemExternalMouse).getItemId()); +// //menu.removeItem(menu.findItem(R.id.itemUIMode).getItemId()); +// +// menu.removeItem(menu.findItem(R.id.itemCtrlAltDel).getItemId()); +// menu.removeItem(menu.findItem(R.id.itemCtrlC).getItemId()); +// +// if (MainSettingsManager.getAlwaysShowMenuToolbar(activity) || Config.mouseMode == Config.MouseMode.External) { +// menu.removeItem(menu.findItem(R.id.itemHideToolbar).getItemId()); +// maxMenuItemsShown--; +// } +// +// if (soundcard==null || soundcard.equals("None")) { +// menu.removeItem(menu.findItem(R.id.itemVolume).getItemId()); +// maxMenuItemsShown--; +// } +// +// +// +// for (int i = 0; i < menu.size() && i < maxMenuItemsShown; i++) { +// MenuItemCompat.setShowAsAction(menu.getItem(i), actionShow); +// } +// +// return true; +// +// } + + private void onMonitor() { + new Thread(new Runnable() { + public void run() { + monitorMode = true; + // final KeyEvent altDown = new KeyEvent(downTime, eventTime, + // KeyEvent.ACTION_DOWN, + // KeyEvent.KEYCODE_2, 1, KeyEvent.META_ALT_LEFT_ON); + sendCtrlAltKey(KeyEvent.KEYCODE_2); + // sendCtrlAltKey(altDown); + Log.v("Vectras", "Monitor On"); + } + }).start(); + + } + + private void onVMConsole() { + monitorMode = false; + sendCtrlAltKey(KeyEvent.KEYCODE_1); + } + + + // FIXME: We need this to able to catch complex characters strings like + // grave and send it as text + @Override + public boolean dispatchKeyEvent(KeyEvent event) { + if (event.getAction() == KeyEvent.ACTION_MULTIPLE && event.getKeyCode() == KeyEvent.KEYCODE_UNKNOWN) { + sendText(event.getCharacters().toString()); + return true; + } else if (event.getKeyCode() == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_DOWN) { + this.onBackPressed(); + return true; + } if (event.getKeyCode() == KeyEvent.KEYCODE_VOLUME_DOWN) { + // We emulate right click with volume down + if(event.getAction() == KeyEvent.ACTION_DOWN) { + MotionEvent e = MotionEvent.obtain(1000, 1000, MotionEvent.ACTION_DOWN, 0, 0, 0, 0, 0, 0, 0, + InputDevice.SOURCE_TOUCHSCREEN, 0); + rightClick(e, 0); + } + return true; + } else if (event.getKeyCode() == KeyEvent.KEYCODE_VOLUME_UP) { + // We emulate middle click with volume up + if(event.getAction() == KeyEvent.ACTION_DOWN) { + MotionEvent e = MotionEvent.obtain(1000, 1000, MotionEvent.ACTION_DOWN, 0, 0, 0, 0, 0, 0, 0, + InputDevice.SOURCE_TOUCHSCREEN, 0); + middleClick(e, 0); + } + return true; + } else { + return super.dispatchKeyEvent(event); + } + + } + + private static void sendText(String string) { + + // Log.v("sendText", string); + KeyCharacterMap keyCharacterMap = KeyCharacterMap.load(KeyCharacterMap.VIRTUAL_KEYBOARD); + KeyEvent[] keyEvents = keyCharacterMap.getEvents(string.toCharArray()); + if (keyEvents != null) + for (int i = 0; i < keyEvents.length; i++) { + + if (keyEvents[i].getAction() == KeyEvent.ACTION_DOWN) { + // Log.v("sendText", "Up: " + keyEvents[i].getKeyCode()); + SDLActivity.onNativeKeyDown(keyEvents[i].getKeyCode()); + } else if (keyEvents[i].getAction() == KeyEvent.ACTION_UP) { + // Log.v("sendText", "Down: " + keyEvents[i].getKeyCode()); + SDLActivity.onNativeKeyUp(keyEvents[i].getKeyCode()); + } + } + } + + + // Setup + protected void onCreate(Bundle savedInstanceState) { + // Log.v("SDL", "onCreate()"); + activity = this; + + if (MainSettingsManager.getFullscreen(this)) + getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, + WindowManager.LayoutParams.FLAG_FULLSCREEN); + + super.onCreate(savedInstanceState); + setupVolume(); + + mSingleton = this; + + Log.v("SDL", "Max Mem = " + Runtime.getRuntime().maxMemory()); + + this.activity1 = this; + + // So we can call stuff from static callbacks + mSingleton = this; + + createUI(0, 0); + + UIUtils.showHints(this); + + this.resumeVM(); + + UIUtils.setOrientation(this); + + + } + + private void createUI(int w, int h) { + //mSurface = new SDLSurface(this); + + int width = w; + int height = h; + if (width == 0) { + width = RelativeLayout.LayoutParams.WRAP_CONTENT; + } + if (height == 0) { + height = RelativeLayout.LayoutParams.WRAP_CONTENT; + } + + setContentView(R.layout.activity_sdl); + + //TODO: + mLayout = (RelativeLayout) activity.findViewById(R.id.sdl_layout); + mMainLayout = (LinearLayout) activity.findViewById(R.id.main_layout); + + RelativeLayout mLayout = (RelativeLayout) findViewById(R.id.sdl); + RelativeLayout.LayoutParams surfaceParams = new RelativeLayout.LayoutParams(width, height); + surfaceParams.addRule(RelativeLayout.CENTER_IN_PARENT); + + mLayout.addView(mSurface, surfaceParams); + + } + + protected void onPause() { + Log.v("SDL", "onPause()"); + MainService.updateServiceNotification(Config.machinename + ": VM Suspended"); + super.onPause(); + + } + + + public void onSelectMenuVol() { + + final AlertDialog alertDialog; + alertDialog = new AlertDialog.Builder(activity, R.style.MainDialogTheme).create(); + alertDialog.setTitle("Volume"); + + LinearLayout.LayoutParams volParams = new LinearLayout.LayoutParams( + LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT); + + LinearLayout t = createVolumePanel(); + t.setLayoutParams(volParams); + + ScrollView s = new ScrollView(activity); + s.addView(t); + alertDialog.setView(s); + alertDialog.setButton(Dialog.BUTTON_POSITIVE, "OK", new DialogInterface.OnClickListener() { + + public void onClick(DialogInterface dialog, int which) { + alertDialog.cancel(); + } + }); + alertDialog.show(); + + } + + public LinearLayout createVolumePanel() { + LinearLayout layout = new LinearLayout (this); + layout.setPadding(20, 20, 20, 20); + + LinearLayout.LayoutParams volparams = new LinearLayout.LayoutParams( + LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT); + + SeekBar vol = new SeekBar(this); + + int volume = 0; + + //TODO: + vol.setMax(maxVolume); + volume = getCurrentVolume(); + + vol.setProgress(volume); + vol.setLayoutParams(volparams); + + ((SeekBar) vol).setOnSeekBarChangeListener(new OnSeekBarChangeListener() { + + public void onProgressChanged(SeekBar s, int progress, boolean touch) { + //TODO: + setVolume(progress); + } + + public void onStartTrackingTouch(SeekBar arg0) { + + } + + public void onStopTrackingTouch(SeekBar arg0) { + + } + }); + + layout.addView(vol); + + return layout; + + } + + protected void onResume() { + Log.v("SDL", "onResume()"); + MainService.updateServiceNotification(Config.machinename + ": VM Running"); + super.onResume(); + } + + // Messages from the SDLMain thread + static int COMMAND_CHANGE_TITLE = 1; + static int COMMAND_SAVEVM = 2; + + public void loadLibraries() { + //XXX: override for the specific arch + } + + + public void promptPause(final Activity activity) { + + final AlertDialog alertDialog; + alertDialog = new AlertDialog.Builder(activity, R.style.MainDialogTheme).create(); + alertDialog.setTitle("Pause VM"); + TextView stateView = new TextView(activity); + stateView.setText("This make take a while depending on the RAM size used"); + stateView.setPadding(20, 20, 20, 20); + alertDialog.setView(stateView); + + alertDialog.setButton(DialogInterface.BUTTON_POSITIVE, "Pause", new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int which) { + onPauseVM(); + return; + } + }); + alertDialog.show(); + } + + private void onPauseVM() { + Thread t = new Thread(new Runnable() { + public void run() { + // Delete any previous state file + if (MainActivityCommon.vmexecutor.save_state_name != null) { + File file = new File(MainActivityCommon.vmexecutor.save_state_name); + if (file.exists()) { + file.delete(); + } + } + if(Config.showToast) + UIUtils.toastShort(getApplicationContext(), "Please wait while saving VM State"); + MainActivityCommon.vmexecutor.current_fd = MainActivityCommon.vmexecutor.get_fd(MainActivityCommon.vmexecutor.save_state_name); + + String uri = "fd:" + MainActivityCommon.vmexecutor.current_fd; + String command = QmpClient.stop(); + String msg = QmpClient.sendCommand(command); + command = QmpClient.migrate(false, false, uri); + msg = QmpClient.sendCommand(command); + if (msg != null) { + processMigrationResponse(msg); + } + + // XXX: Instead we poll to see if migration is complete + new Handler(Looper.getMainLooper()).postDelayed(new Runnable() { + @Override + public void run() { + VMListener a = new VMListener(); + a.execute(); + } + }, 0); + } + }); + t.start(); + + } + + private void processMigrationResponse(String response) { + String errorStr = null; + try { + JSONObject object = new JSONObject(response); + errorStr = object.getString("error"); + }catch (Exception ex) { + if(Config.debug) + ex.printStackTrace(); + } + if (errorStr != null) { + String descStr = null; + + try { + JSONObject descObj = new JSONObject(errorStr); + descStr = descObj.getString("desc"); + }catch (Exception ex) { + if(Config.debug) + ex.printStackTrace(); + } + final String descStr1 = descStr; + + new Handler(Looper.getMainLooper()).postDelayed(new Runnable() { + @Override + public void run() { + Machine.pausedErrorVM(activity, descStr1); + } + }, 100); + + } + + } + + private class VMListener extends AsyncTask { + + @Override + protected Void doInBackground(Void... arg0) { + startTimeListener(); + return null; + } + + @Override + protected void onPostExecute(Void test) { + + } + } + + @Override + public boolean onTouchEvent(MotionEvent event) { + boolean res = false; + if(Config.mouseMode == Config.MouseMode.External){ + return res; + } + //TODO: + //vsdlres = ((VectrasSDLSurface) this.mSurface).onTouchProcess(this.mSurface, event); + //vsdlres = ((VectrasSDLSurface) this.mSurface).onTouchEventProcess(event); + return true; + } + + private void resumeVM() { + if(MainActivityCommon.vmexecutor == null){ + return; + } + Thread t = new Thread(new Runnable() { + public void run() { + if (MainActivityCommon.vmexecutor.paused == 1) { + + try { + Thread.sleep(4000); + } catch (InterruptedException ex) { + Logger.getLogger(MainVNCActivity.class.getName()).log(Level.SEVERE, null, ex); + } + MainActivityCommon.vmexecutor.paused = 0; + + String command = QmpClient.cont(); + String msg = QmpClient.sendCommand(command); + new Handler(Looper.getMainLooper()).postDelayed(new Runnable() { + @Override + public void run() { + if(Config.mouseMode == Config.MouseMode.External) + setUIModeDesktop(); + else + setUIModeMobile(screenMode == SDLScreenMode.FitToScreen); + } + }, 500); + } + } + }); + t.start(); + + } + + public void onBackPressed() { + if (!MainSettingsManager.getAlwaysShowMenuToolbar(activity)) { + ActionBar bar = this.getSupportActionBar(); + if (bar != null) { + if (bar.isShowing()) + bar.hide(); + else + bar.show(); + } + } else { + UIUtils.hideKeyboard(this, mSurface); + Machine.stopVM(activity); + } + + } + + @Override + public void onConfigurationChanged(Configuration newConfig) { + super.onConfigurationChanged(newConfig); + this.invalidateOptionsMenu(); + } + + public void onSelectMenuSDLDisplay() { + + final AlertDialog alertDialog; + alertDialog = new AlertDialog.Builder(activity, R.style.MainDialogTheme).create(); + alertDialog.setTitle("Display"); + + LinearLayout.LayoutParams volParams = new LinearLayout.LayoutParams( + LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT); + + LinearLayout t = createSDLDisplayPanel(); + t.setLayoutParams(volParams); + + ScrollView s = new ScrollView(activity); + s.addView(t); + alertDialog.setView(s); + alertDialog.setButton(Dialog.BUTTON_POSITIVE, "OK", new DialogInterface.OnClickListener() { + + public void onClick(DialogInterface dialog, int which) { + alertDialog.cancel(); + } + }); + alertDialog.show(); + + } + + + public LinearLayout createSDLDisplayPanel() { + LinearLayout layout = new LinearLayout(this); + layout.setOrientation(LinearLayout.VERTICAL); + layout.setPadding(20, 20, 20, 20); + + LinearLayout.LayoutParams params = new LinearLayout.LayoutParams( + LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT); + int currRate = getCurrentSDLRefreshRate(); + + LinearLayout buttonsLayout = new LinearLayout(this); + buttonsLayout.setOrientation(LinearLayout.HORIZONTAL); + buttonsLayout.setGravity(Gravity.CENTER_HORIZONTAL); + Button displayMode = new Button (this); + + displayMode.setText("Display Mode"); + displayMode.setOnClickListener(new View.OnClickListener() { + public void onClick(View view) { + onDisplayMode(); + } + }); + buttonsLayout.addView(displayMode); + layout.addView(buttonsLayout); + + final TextView value = new TextView(this); + value.setText("Idle Refresh Rate: " + currRate+" Hz"); + layout.addView(value); + value.setLayoutParams(params); + + SeekBar rate = new SeekBar(this); + rate.setMax(Config.MAX_DISPLAY_REFRESH_RATE); + + rate.setProgress(currRate); + rate.setLayoutParams(params); + + ((SeekBar) rate).setOnSeekBarChangeListener(new OnSeekBarChangeListener() { + + public void onProgressChanged(SeekBar s, int progress, boolean touch) { + value.setText("Idle Refresh Rate: " + (progress+1)+" Hz"); + } + + public void onStartTrackingTouch(SeekBar arg0) { + + } + + public void onStopTrackingTouch(SeekBar arg0) { + int progress = arg0.getProgress()+1; + int refreshMs = 1000 / progress; + Log.v(TAG, "Changing idle refresh rate: (ms)" + refreshMs); + MainActivityCommon.vmexecutor.setsdlrefreshrate(refreshMs); + } + }); + + + layout.addView(rate); + + return layout; + + } + + public int getCurrentSDLRefreshRate() { + return 1000 / MainActivityCommon.vmexecutor.getsdlrefreshrate(); + } + + + + private void onDisplayMode() { + + String [] items = { + "Normal (One-To-One)", + "Fit To Screen" +// ,"Stretch To Screen" //Stretched + }; + int currentScaleType = 0; + if(screenMode == SDLScreenMode.FitToScreen){ + currentScaleType = 1; + } else if(screenMode == SDLScreenMode.Fullscreen) + currentScaleType = 2; + + final AlertDialog.Builder mBuilder = new AlertDialog.Builder(this); + mBuilder.setTitle("Display Mode"); + mBuilder.setSingleChoiceItems(items, currentScaleType, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int i) { + switch(i){ + case 0: + onNormalScreen(); + break; + case 1: + if(Config.mouseMode == Config.MouseMode.External){ + UIUtils.toastShort(MainSDLActivity.this, "Fit to Screen Disabled under Desktop Mode"); + dialog.dismiss(); + return; + } + onFitToScreen(); + break; + case 2: + if(Config.mouseMode == Config.MouseMode.External){ + UIUtils.toastShort(MainSDLActivity.this, "Stretch Screen Disabled under Desktop Mode"); + dialog.dismiss(); + return; + } + onStretchToScreen(); + break; + default: + break; + } + dialog.dismiss(); + } + }); + final AlertDialog alertDialog = mBuilder.create(); + alertDialog.show(); + + } + + + @Override + protected synchronized void runSDLMain(){ + + //We go through the vm executor + MainActivityCommon.startvm(this, Config.UI_SDL); + + //XXX: we hold the thread because SDLActivity will exit + try { + wait(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + public static void onVMResolutionChanged(int w, int h) + { + boolean refreshDisplay = false; + + if(w!=vm_width || h!=vm_height) + refreshDisplay = true; + vm_width = w; + vm_height = h; + + Log.v(TAG, "VM resolution changed to " + vm_width + "x" + vm_height); + + + if(refreshDisplay) { + activity.resize(null); + } + + } + + public static boolean isResizing = false; + + public enum SDLScreenMode { + Normal, + FitToScreen, + Fullscreen //fullscreen not implemented yet + } + + public SDLScreenMode screenMode = SDLScreenMode.FitToScreen; + + private void setLayout(Configuration newConfig) { + + boolean isLanscape = + (newConfig!=null && newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) + || UIUtils.isLandscapeOrientation(this); + + View vnc_canvas_layout = (View) this.findViewById(R.id.sdl_layout); + RelativeLayout.LayoutParams vnc_canvas_layout_params = null; + //normal 1-1 + if(screenMode == SDLScreenMode.Normal) { + if (isLanscape) { + vnc_canvas_layout_params = new RelativeLayout.LayoutParams( + ViewGroup.LayoutParams.WRAP_CONTENT, + ViewGroup.LayoutParams.WRAP_CONTENT + ); +// vnc_canvas_layout_params.addRule(RelativeLayout.CENTER_IN_PARENT); + vnc_canvas_layout_params.addRule(RelativeLayout.ALIGN_PARENT_TOP); + vnc_canvas_layout_params.addRule(RelativeLayout.CENTER_HORIZONTAL); + + } else { + vnc_canvas_layout_params = new RelativeLayout.LayoutParams( + ViewGroup.LayoutParams.WRAP_CONTENT, + ViewGroup.LayoutParams.WRAP_CONTENT + ); + vnc_canvas_layout_params.addRule(RelativeLayout.ALIGN_PARENT_TOP); + vnc_canvas_layout_params.addRule(RelativeLayout.CENTER_HORIZONTAL); + } + } else { + //fittoscreen + if (isLanscape) { + vnc_canvas_layout_params = new RelativeLayout.LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.MATCH_PARENT + ); + vnc_canvas_layout_params.addRule(RelativeLayout.CENTER_IN_PARENT); + } else { + + vnc_canvas_layout_params = new RelativeLayout.LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.WRAP_CONTENT + ); + vnc_canvas_layout_params.addRule(RelativeLayout.ALIGN_PARENT_TOP); + vnc_canvas_layout_params.addRule(RelativeLayout.CENTER_HORIZONTAL); + } + } + vnc_canvas_layout.setLayoutParams(vnc_canvas_layout_params); + + this.invalidateOptionsMenu(); + } + + /*public class VectrasSDLSurface extends ExSDLSurface implements View.OnKeyListener, View.OnTouchListener { + + public boolean initialized = false; + + public VectrasSDLSurface(Context context) { + super(context); + setOnKeyListener(this); + setOnTouchListener(this); + gestureDetector = new GestureDetector(activity, new GestureListener()); + setOnGenericMotionListener(new SDLGenericMotionListener_API12()); + } + + public void surfaceChanged(SurfaceHolder holder, + int format, int width, int height) { + super.surfaceChanged(holder, format, width, height); + new Handler(Looper.getMainLooper()).postDelayed(new Runnable() { + @Override + public void run() { + + SDLActivity.onNativeKeyDown(KeyEvent.KEYCODE_CTRL_LEFT); + SDLActivity.onNativeKeyUp(KeyEvent.KEYCODE_CTRL_LEFT); + } + }, 500); + } + + @Override + public void surfaceCreated(SurfaceHolder holder) { + super.surfaceCreated(holder); + + new Handler(Looper.getMainLooper()).postDelayed(new Runnable() { + @Override + public void run() { + + if(Config.mouseMode == Config.MouseMode.External) + setUIModeDesktop(); + else + setUIModeMobile(screenMode == SDLScreenMode.FitToScreen); + } + },1000); + } + + @Override + public void onConfigurationChanged(Configuration newConfig) { + super.onConfigurationChanged(newConfig); + Log.d(TAG,"Configuration changed"); + resize(newConfig); + } + + + + public synchronized void doResize(boolean reverse, final Configuration newConfig) { + //XXX: notify the UI not to process mouse motion + isResizing = true; + Log.v(TAG, "Resizing Display"); + + Display display = SDLActivity.mSingleton.getWindowManager().getDefaultDisplay(); + int height = 0; + int width = 0; + + Point size = new Point(); + display.getSize(size); + int screen_width = size.x; + int screen_height = size.y; + + final ActionBar bar = ((SDLActivity) activity).getSupportActionBar(); + + if(MainSDLActivity.mLayout != null) { + width = MainSDLActivity.mLayout.getWidth(); + height = MainSDLActivity.mLayout.getHeight(); + } + + //native resolution for use with external mouse + if(screenMode != SDLScreenMode.Fullscreen && screenMode != SDLScreenMode.FitToScreen) { + width = MainSDLActivity.vm_width; + height = MainSDLActivity.vm_height; + } + + if(reverse){ + int temp = width; + width = height; + height = temp; + } + + boolean portrait = SDLActivity.mSingleton.getResources() + .getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT; + + if (portrait) { + if(Config.mouseMode != Config.MouseMode.External) { + int height_n = (int) (width / (MainSDLActivity.vm_width / (float) MainSDLActivity.vm_height)); + Log.d(TAG, "Resizing portrait: " + width + " x " + height_n); + getHolder().setFixedSize(width, height_n); + } + } else { + if ( (screenMode == SDLScreenMode.Fullscreen || screenMode == SDLScreenMode.FitToScreen) + && !MainSettingsManager.getAlwaysShowMenuToolbar(MainSDLActivity.this) + && bar != null && bar.isShowing()) { + height += bar.getHeight(); + } + Log.d(TAG, "Resizing landscape: " + width + " x " + height); + getHolder().setFixedSize(width, height); + } + initialized = true; + + new Handler(Looper.getMainLooper()).postDelayed(new Runnable() { + @Override + public void run() { + isResizing = false; + } + }, 1000); + + + + } + + // XXX: SDL is missing some key codes in sdl2-keymap.h + // So we create them with a Shift Modifier + private boolean handleMissingKeys(int keyCode, int action) { + + int keyCodeTmp = keyCode; + switch (keyCode) { + case 77: + keyCodeTmp = 9; + break; + case 81: + keyCodeTmp = 70; + break; + case 17: + keyCodeTmp = 15; + break; + case 18: + keyCodeTmp = 10; + break; + default: + return false; + + } + if (action == KeyEvent.ACTION_DOWN) { + SDLActivity.onNativeKeyDown(59); + SDLActivity.onNativeKeyDown(keyCodeTmp); + } else { + SDLActivity.onNativeKeyUp(59); + SDLActivity.onNativeKeyUp(keyCodeTmp); + } + return true; + + } + + @Override + public boolean onKey(View v, int keyCode, KeyEvent event) { + + if ((keyCode == KeyEvent.KEYCODE_BACK) || (keyCode == KeyEvent.KEYCODE_FORWARD)) { + // dismiss android back and forward keys + return true; + } else if (event.getKeyCode() == KeyEvent.KEYCODE_MENU) { + return false; + } else if (event.getAction() == KeyEvent.ACTION_DOWN) { + //Log.v("SDL", "key down: " + keyCode); + if (!handleMissingKeys(keyCode, event.getAction())) + SDLActivity.onNativeKeyDown(keyCode); + return true; + } else if (event.getAction() == KeyEvent.ACTION_UP) { + //Log.v("SDL", "key up: " + keyCode); + if (!handleMissingKeys(keyCode, event.getAction())) + SDLActivity.onNativeKeyUp(keyCode); + return true; + } else { + return super.onKey(v, keyCode, event); + } + + } + + // Touch events + public boolean onTouchProcess(View v, MotionEvent event) { + int action = event.getAction(); + float x = event.getX(0); + float y = event.getY(0); + float p = event.getPressure(0); + + int relative = Config.mouseMode == Config.MouseMode.External? 0: 1; + + int sdlMouseButton = 0; + if(event.getButtonState() == MotionEvent.BUTTON_PRIMARY) + sdlMouseButton = Config.SDL_MOUSE_LEFT; + else if(event.getButtonState() == MotionEvent.BUTTON_SECONDARY) + sdlMouseButton = Config.SDL_MOUSE_RIGHT; + else if(event.getButtonState() == MotionEvent.BUTTON_TERTIARY) + sdlMouseButton = Config.SDL_MOUSE_MIDDLE; + + + if (event.getAction() == MotionEvent.ACTION_MOVE) { + + if (mouseUp) { + old_x = x; + old_y = y; + mouseUp = false; + } + if (action == MotionEvent.ACTION_MOVE) { + if(Config.mouseMode == Config.MouseMode.External) { + //Log.d("SDL", "onTouch Absolute Move by=" + action + ", X,Y=" + (x) + "," + (y) + " P=" + p); + MainActivityCommon.vmexecutor.onVectrasMouse(0, MotionEvent.ACTION_MOVE,0, x , y ); + }else { + //Log.d("SDL", "onTouch Relative Moving by=" + action + ", X,Y=" + (x - +// old_x) + "," + (y - old_y) + " P=" + p); + MainActivityCommon.vmexecutor.onVectrasMouse(0, MotionEvent.ACTION_MOVE,1, (x - old_x) * sensitivity_mult, (y - old_y) * sensitivity_mult); + } + + } + // save current + old_x = x; + old_y = y; + + } + else if (event.getAction() == event.ACTION_UP ) { + //Log.d("SDL", "onTouch Up: " + sdlMouseButton); + //XXX: it seems that the Button state is not available when Button up so + // we should release all mouse buttons to be safe since we don't know which one fired the event + if(sdlMouseButton == Config.SDL_MOUSE_MIDDLE + ||sdlMouseButton == Config.SDL_MOUSE_RIGHT + ) { + MainActivityCommon.vmexecutor.onVectrasMouse(sdlMouseButton, MotionEvent.ACTION_UP, relative, x, y); + } else if (sdlMouseButton != 0) { + MainActivityCommon.vmexecutor.onVectrasMouse(sdlMouseButton, MotionEvent.ACTION_UP, relative, x, y); + } else { // if we don't have inforamtion about which button we can make some guesses + + //Or only the last one pressed + if (lastMouseButtonDown > 0) { + if(lastMouseButtonDown == Config.SDL_MOUSE_MIDDLE + ||lastMouseButtonDown == Config.SDL_MOUSE_RIGHT + ) { + MainActivityCommon.vmexecutor.onVectrasMouse(lastMouseButtonDown, MotionEvent.ACTION_UP, relative,x, y); + }else + MainActivityCommon.vmexecutor.onVectrasMouse(lastMouseButtonDown, MotionEvent.ACTION_UP, relative, x, y); + } else { + //ALl buttons + if (Config.mouseMode == Config.MouseMode.Trackpad) { + MainActivityCommon.vmexecutor.onVectrasMouse(Config.SDL_MOUSE_LEFT, MotionEvent.ACTION_UP, 1, 0, 0); + } else if (Config.mouseMode == Config.MouseMode.External) { + MainActivityCommon.vmexecutor.onVectrasMouse(Config.SDL_MOUSE_LEFT, MotionEvent.ACTION_UP, 0, x, y); + MainActivityCommon.vmexecutor.onVectrasMouse(Config.SDL_MOUSE_RIGHT, MotionEvent.ACTION_UP, 0, x, y); + MainActivityCommon.vmexecutor.onVectrasMouse(Config.SDL_MOUSE_MIDDLE, MotionEvent.ACTION_UP, 0, x, y); + } + } + } + lastMouseButtonDown = -1; + mouseUp = true; + } + else if (event.getAction() == event.ACTION_DOWN + && Config.mouseMode == Config.MouseMode.External + ) { + + //XXX: Some touch events for touchscreen mode are primary so we force left mouse button + if(sdlMouseButton == 0 && MotionEvent.TOOL_TYPE_FINGER == event.getToolType(0)) { + sdlMouseButton = Config.SDL_MOUSE_LEFT; + } + + MainActivityCommon.vmexecutor.onVectrasMouse(sdlMouseButton, MotionEvent.ACTION_DOWN, relative, x, y); + lastMouseButtonDown = sdlMouseButton; + } + return true; + } + + public boolean onTouch(View v, MotionEvent event) { + boolean res = false; + if(Config.mouseMode == Config.MouseMode.External){ + res = onTouchProcess(v,event); + res = onTouchEventProcess(event); + } + return res; + } + + public boolean onTouchEvent(MotionEvent event) { + return false; + } + + public boolean onTouchEventProcess(MotionEvent event) { + // Log.v("onTouchEvent", + // "Action=" + event.getAction() + ", X,Y=" + event.getX() + "," + // + event.getY() + " P=" + event.getPressure()); + // MK + if (event.getAction() == MotionEvent.ACTION_CANCEL) + return true; + + if (!firstTouch) { + firstTouch = true; + } + if (event.getPointerCount() > 1) { + + // XXX: Vectras Legacy enable Right Click with 2 finger touch + // Log.v("Right Click", + // "Action=" + event.getAction() + ", X,Y=" + event.getX() + // + "," + event.getY() + " P=" + event.getPressure()); + // rightClick(event); + return true; + } else + return gestureDetector.onTouchEvent(event); + } + } +*/ + public AudioManager am; + protected int maxVolume; + + protected void setupVolume() { + if (am == null) { + am = (AudioManager) mSingleton.getSystemService(Context.AUDIO_SERVICE); + maxVolume = am.getStreamMaxVolume(AudioManager.STREAM_MUSIC); + } + } + + public void setVolume(int volume) { + if(am!=null) + am.setStreamVolume(AudioManager.STREAM_MUSIC, volume, 0); + } + + protected int getCurrentVolume() { + int volumeTmp = 0; + if(am!=null) + volumeTmp = am.getStreamVolume(AudioManager.STREAM_MUSIC); + return volumeTmp; + } + + + //XXX: We want to suspend only when app is calling onPause() + @Override + public void onWindowFocusChanged(boolean hasFocus) { + + } + + public boolean rightClick(final MotionEvent e, final int i) { + Thread t = new Thread(new Runnable() { + public void run() { + Log.d("SDL", "Mouse Right Click"); + MainActivityCommon.vmexecutor.onVectrasMouse(Config.SDL_MOUSE_RIGHT, MotionEvent.ACTION_DOWN, 1, -1, -1); + try { + Thread.sleep(100); + } catch (InterruptedException ex) { +// Log.v("SDLSurface", "Interrupted: " + ex); + } + MainActivityCommon.vmexecutor.onVectrasMouse(Config.SDL_MOUSE_RIGHT, MotionEvent.ACTION_UP, 1, -1, -1); + } + }); + t.start(); + return true; + + } + + public boolean middleClick(final MotionEvent e, final int i) { + Thread t = new Thread(new Runnable() { + public void run() { + Log.d("SDL", "Mouse Middle Click"); + MainActivityCommon.vmexecutor.onVectrasMouse(Config.SDL_MOUSE_MIDDLE, MotionEvent.ACTION_DOWN, 1,-1, -1); + try { + Thread.sleep(100); + } catch (InterruptedException ex) { +// Log.v("SDLSurface", "Interrupted: " + ex); + } + MainActivityCommon.vmexecutor.onVectrasMouse(Config.SDL_MOUSE_MIDDLE, MotionEvent.ACTION_UP, 1,-1, -1); + } + }); + t.start(); + return true; + + } + + private void doubleClick(final MotionEvent event, final int pointer_id) { + + Thread t = new Thread(new Runnable() { + public void run() { + //Log.d("SDL", "Mouse Double Click"); + for (int i = 0; i < 2; i++) { + MainActivityCommon.vmexecutor.onVectrasMouse(Config.SDL_MOUSE_LEFT, MotionEvent.ACTION_DOWN, 1, 0, 0); + try { + Thread.sleep(50); + } catch (InterruptedException ex) { + // Log.v("doubletap", "Could not sleep"); + } + MainActivityCommon.vmexecutor.onVectrasMouse(Config.SDL_MOUSE_LEFT, MotionEvent.ACTION_UP, 1,0, 0); + try { + Thread.sleep(50); + } catch (InterruptedException ex) { + // Log.v("doubletap", "Could not sleep"); + } + } + } + }); + t.start(); + } + + + int lastMouseButtonDown = -1; + public float old_x = 0; + public float old_y = 0; + private boolean mouseUp = true; + private float sensitivity_mult = (float) 1.0; + private boolean firstTouch = false; + + + + private class GestureListener extends GestureDetector.SimpleOnGestureListener { + + @Override + public boolean onDown(MotionEvent event) { + // Log.v("onDown", "Action=" + event.getAction() + ", X,Y=" + event.getX() + // + "," + event.getY() + " P=" + event.getPressure()); + return true; + } + + @Override + public void onLongPress(MotionEvent event) { + // Log.d("SDL", "Long Press Action=" + event.getAction() + ", X,Y=" + // + event.getX() + "," + event.getY() + " P=" + // + event.getPressure()); + if(Config.mouseMode == Config.MouseMode.External) + return; + + if(Config.enableDragOnLongPress) + dragPointer(event); + } + + public boolean onSingleTapConfirmed(MotionEvent event) { + float x1 = event.getX(); + float y1 = event.getY(); + + if(Config.mouseMode == Config.MouseMode.External) + return true; + +// Log.d("onSingleTapConfirmed", "Tapped at: (" + x1 + "," + y1 + +// ")"); + + for (int i = 0; i < event.getPointerCount(); i++) { + int action = event.getAction(); + float x = event.getX(i); + float y = event.getY(i); + float p = event.getPressure(i); + + //Log.v("onSingleTapConfirmed", "Action=" + action + ", X,Y=" + x + "," + y + " P=" + p); + if (event.getAction() == event.ACTION_DOWN + && MotionEvent.TOOL_TYPE_FINGER == event.getToolType(0)) { + //Log.d("SDL", "onTouch Down: " + event.getButtonState()); + MainSDLActivity.singleClick(event, i); + } + } + return true; + + } + + // event when double tap occurs + @Override + public boolean onDoubleTap(MotionEvent event) { +// Log.d("onDoubleTap", "Tapped at: (" + event.getX() + "," + event.getY() + ")"); + + if(Config.mouseMode == Config.MouseMode.External + //&& MotionEvent.TOOL_TYPE_MOUSE == event.getToolType(0) + ) + return true; + + if(!Config.enableDragOnLongPress) + processDoubleTap(event); + else + doubleClick(event, 0); + + return true; + } + } + + private void dragPointer(MotionEvent event) { + + MainActivityCommon.vmexecutor.onVectrasMouse(Config.SDL_MOUSE_LEFT, MotionEvent.ACTION_DOWN, 1, 0, 0); + Vibrator v = (Vibrator) activity.getSystemService(Context.VIBRATOR_SERVICE); + if (v.hasVibrator()) { + v.vibrate(100); + } + } + + private void processDoubleTap(final MotionEvent event) { + + Thread t = new Thread(new Runnable() { + public void run() { + try { + Thread.sleep(400); + } catch (InterruptedException e1) { + e1.printStackTrace(); + } + + if (!mouseUp) { + dragPointer(event); + } else { + // Log.v("onDoubleTap", "Action=" + action + ", X,Y=" + x + "," + y + " P=" + p); + doubleClick(event, 0); + } + + } + }); + t.start(); + + } + + class SDLGenericMotionListener_API12 implements View.OnGenericMotionListener { + private ExSDLSurface mSurface; + + @Override + public boolean onGenericMotion(View v, MotionEvent event) { + float x, y; + int action; + + switch (event.getSource()) { + case InputDevice.SOURCE_JOYSTICK: + case InputDevice.SOURCE_GAMEPAD: + case InputDevice.SOURCE_DPAD: + SDLControllerManager.handleJoystickMotionEvent(event); + return true; + + case InputDevice.SOURCE_MOUSE: + if(Config.mouseMode == Config.MouseMode.Trackpad) + break; + + action = event.getActionMasked(); +// Log.d("SDL", "onGenericMotion, action = " + action + "," + event.getX() + ", " + event.getY()); + switch (action) { + case MotionEvent.ACTION_SCROLL: + x = event.getAxisValue(MotionEvent.AXIS_HSCROLL, 0); + y = event.getAxisValue(MotionEvent.AXIS_VSCROLL, 0); +// Log.d("SDL", "Mouse Scroll: " + x + "," + y); + MainActivityCommon.vmexecutor.onVectrasMouse(0, action, 0, x, y); + return true; + + case MotionEvent.ACTION_HOVER_MOVE: + if(Config.processMouseHistoricalEvents) { + final int historySize = event.getHistorySize(); + for (int h = 0; h < historySize; h++) { + float ex = event.getHistoricalX(h); + float ey = event.getHistoricalY(h); + float ep = event.getHistoricalPressure(h); + processHoverMouse(ex, ey, ep, action); + } + } + + float ex = event.getX(); + float ey = event.getY(); + float ep = event.getPressure(); + processHoverMouse(ex, ey, ep, action); + return true; + + case MotionEvent.ACTION_UP: + + default: + break; + } + break; + + default: + break; + } + + // Event was not managed + return false; + } + + private void processHoverMouse(float x,float y,float p, int action) { + + + + if(Config.mouseMode == Config.MouseMode.External) { + //Log.d("SDL", "Mouse Hover: " + x + "," + y); + MainActivityCommon.vmexecutor.onVectrasMouse(0, action, 0, x, y); + } + } + + } + + GestureDetector gestureDetector; + +} diff --git a/app/src/main/java/com/vectras/qemu/MainService.java b/app/src/main/java/com/vectras/qemu/MainService.java new file mode 100644 index 0000000..85c7fa3 --- /dev/null +++ b/app/src/main/java/com/vectras/qemu/MainService.java @@ -0,0 +1,236 @@ +package com.vectras.qemu; + +import android.app.Notification; +import android.app.NotificationChannel; +import android.app.NotificationManager; +import android.app.PendingIntent; +import android.app.Service; +import android.content.Context; +import android.content.Intent; +import android.graphics.BitmapFactory; +import android.net.wifi.WifiManager; +import android.net.wifi.WifiManager.WifiLock; +import android.os.Build; +import android.os.Bundle; +import android.os.Handler; +import android.os.IBinder; +import android.os.Looper; +import android.os.PowerManager; +import android.os.PowerManager.WakeLock; +import android.util.Log; +import android.view.View; + +import androidx.core.app.NotificationCompat; + +import com.vectras.qemu.jni.StartVM; +import com.vectras.qemu.utils.FileUtils; +import com.vectras.vm.Fragment.HomeFragment; +import com.vectras.vm.MainActivity; +import com.vectras.vm.R; + +public class MainService extends Service { + + private static final String TAG = "MainService"; + private static Notification mNotification; + private static WifiLock mWifiLock; + public static MainService service; + private static WakeLock mWakeLock; + public static boolean isRunning; + private NotificationManager mNotificationManager; + + @Override + public IBinder onBind(Intent arg0) { + + return null; + } + + public static StartVM executor; + private static NotificationCompat.Builder builder; + + public static final int notifID = 1000; + + @Override + public int onStartCommand(Intent intent, int flags, int startId) { + final String action = intent.getAction(); + final Bundle b = intent.getExtras(); + final int ui = b.getInt("ui", 0); + + if (action.equals(Config.ACTION_START)) { + setUpAsForeground(Config.machinename + " VM Running"); + + FileUtils.startLogging(); + + scheduleTimer(); + + Thread t = new Thread(new Runnable() { + public void run() { + + //XXX: wait till logging starts capturing + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + Log.v(TAG, "Starting VM " + Config.machinename); + + setupLocks(); + + if (ui == Config.UI_VNC) { + + new Handler(Looper.getMainLooper()).postDelayed(new Runnable() { + + @Override + public void run() { + MainActivityCommon.startvnc(); + } + }, 2000); + } + + //Start vm + String res = executor.startvm(); + + //VM has exited + MainActivityCommon.cleanup(); + + } + }); + t.setName("StartVM"); + t.start(); + + + } + + + // Don't restart if killed + return START_NOT_STICKY; + } + + private void scheduleTimer() { + Thread t = new Thread(new Runnable() { + public void run() { + try { + Thread.sleep(2000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + MainActivityCommon.startTimer(); + } + }); + t.start(); + } + + + private void setUpAsForeground(String text) { + isRunning = true; + MainActivityCommon.vmStarted = true; + Class clientClass = null; + if (Config.ui != null) { + if (Config.ui.equals("VNC")) { + if (MainSettingsManager.getVncExternal(MainActivityCommon.activity)) { + MainActivity.extVncLayout.setVisibility(View.VISIBLE); + MainActivity.appbar.setExpanded(true); + } + clientClass = MainVNCActivity.class; + } else if (Config.ui.equals("SDL")) { + clientClass = MainSDLActivity.class; + } else { + Log.e(TAG, "Unknown User Interface"); + return; + } + } else { + // UIUtils.toastLong(service, "Machine UI is not set"); + //using VNC by default + clientClass = MainVNCActivity.class; + } + Intent intent = new Intent(service.getApplicationContext(), clientClass); + + PendingIntent pi = PendingIntent.getActivity(service.getApplicationContext(), 0, intent, + PendingIntent.FLAG_IMMUTABLE); + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + NotificationChannel chan = new NotificationChannel(Config.notificationChannelID, Config.notificationChannelName, NotificationManager.IMPORTANCE_NONE); + NotificationManager notifService = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); + notifService.createNotificationChannel(chan); + builder = new NotificationCompat.Builder(service, Config.notificationChannelID); + + } else + builder = new NotificationCompat.Builder(service, ""); + mNotification = builder.setContentIntent(pi).setContentTitle(getString(R.string.app_name)).setContentText(text) + .setSmallIcon(R.mipmap.ic_launcher) + .setLargeIcon(BitmapFactory.decodeResource(service.getResources(), R.mipmap.ic_launcher)).build(); + mNotification.tickerText = text; + mNotification.flags |= Notification.FLAG_ONGOING_EVENT; + + service.startForeground(notifID, mNotification); + + + } + + public static void updateServiceNotification(String text) { + if (builder != null) { + builder.setContentText(text); + mNotification = builder.build(); + // mNotification.tickerText = text ; + + NotificationManager mNotificationManager = (NotificationManager) + service.getApplicationContext().getSystemService(Context.NOTIFICATION_SERVICE); + // mId allows you to update the notification later on. + mNotificationManager.notify(notifID, mNotification); + } + } + + @Override + public void onCreate() { + Log.d(TAG, "Creating Service"); + service = this; + } + + private void setupLocks() { + + mWifiLock = ((WifiManager) service.getApplicationContext().getSystemService(Context.WIFI_SERVICE)) + .createWifiLock(WifiManager.WIFI_MODE_FULL_HIGH_PERF, Config.wifiLockTag); + mWifiLock.setReferenceCounted(false); + + PowerManager pm = (PowerManager) service.getApplicationContext().getSystemService(Context.POWER_SERVICE); + mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, Config.wakeLockTag); + mWakeLock.setReferenceCounted(false); + + mNotificationManager = (NotificationManager) service.getApplicationContext().getSystemService(NOTIFICATION_SERVICE); + + } + + private static void releaseLocks() { + + if (mWifiLock != null && mWifiLock.isHeld()) { + Log.d(TAG, "Release Wifi lock..."); + mWifiLock.release(); + } + + if (mWakeLock != null && mWakeLock.isHeld()) { + Log.d(TAG, "Release Wake lock..."); + mWakeLock.release(); + } + + } + + public static void stopService() { + + Thread t = new Thread(new Runnable() { + public void run() { + releaseLocks(); + if (service != null) { + service.stopForeground(true); + service.stopSelf(); + isRunning = false; + } + + } + }); + t.setName("StartVM"); + t.start(); + + + } + +} diff --git a/app/src/main/java/com/vectras/qemu/MainSettingsManager.java b/app/src/main/java/com/vectras/qemu/MainSettingsManager.java new file mode 100644 index 0000000..72db3dc --- /dev/null +++ b/app/src/main/java/com/vectras/qemu/MainSettingsManager.java @@ -0,0 +1,585 @@ +/* +Copyright (C) Max Kastanas 2012 + + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package com.vectras.qemu; + +import android.app.Activity; +import android.content.Context; +import android.content.SharedPreferences; +import android.content.SharedPreferences.OnSharedPreferenceChangeListener; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; +import android.os.Bundle; +import android.os.Environment; +import android.preference.PreferenceActivity; +import android.preference.PreferenceManager; +import android.view.MenuItem; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.widget.Toolbar; +import androidx.preference.Preference; +import androidx.preference.PreferenceFragment; +import androidx.preference.PreferenceFragmentCompat; +import com.vectras.vm.R; + +import java.util.List; + +public class MainSettingsManager extends AppCompatActivity { + + private static final String TAG = "SettingsActivity"; + public static MainSettingsManager activity; + public static SharedPreferences sp; + + public static int fragment = 0; + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_settings); + activity = this; + + fragment = 0; + + Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); + setSupportActionBar(toolbar); + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + getSupportActionBar().setDisplayShowHomeEnabled(true); + toolbar.setTitle("Settings"); + } + @Override + public boolean onOptionsItemSelected(@NonNull MenuItem item) { + if(item.getItemId()== android.R.id.home){ + if (fragment == 0) { + finish(); + } else { + MainFragment.mainFragment(); + } + } + return super.onOptionsItemSelected(item); + } + + public static class MainFragment extends PreferenceFragmentCompat { + + public static MainFragment fr; + @Override + public void onCreatePreferences(@Nullable Bundle savedInstanceState, @Nullable String rootKey) { + setPreferencesFromResource(R.xml.headers_preference, rootKey); + fr = MainFragment.this; + fragment = 0; + findPreference("app").setOnPreferenceClickListener(preference -> { + getFragmentManager().beginTransaction().replace(R.id.settingz, + new AppPreferencesFragment()).commit(); + return false; + }); + findPreference("userinterface").setOnPreferenceClickListener(preference -> { + getFragmentManager().beginTransaction().replace(R.id.settingz, + new UserInterfacePreferencesFragment()).commit(); + return false; + }); + findPreference("qemu").setOnPreferenceClickListener(preference -> { + getFragmentManager().beginTransaction().replace(R.id.settingz, + new QemuPreferencesFragment()).commit(); + return false; + }); + findPreference("vnc").setOnPreferenceClickListener(preference -> { + getFragmentManager().beginTransaction().replace(R.id.settingz, + new VncPreferencesFragment()).commit(); + return false; + }); + } + public static void mainFragment(){ + fr.getFragmentManager().beginTransaction().replace(R.id.settingz, + new MainFragment()).commit(); + } + + @Override + public void onResume() { + super.onResume(); + fragment = 0; + } + + @Override + public void onPause() { + super.onPause(); + fragment = 0; + } + + } + + public static class AppPreferencesFragment extends PreferenceFragmentCompat + implements OnSharedPreferenceChangeListener { + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + sp = getPreferenceScreen().getSharedPreferences(); + + Toolbar toolbar = (Toolbar) activity.findViewById(R.id.toolbar); + activity.setSupportActionBar(toolbar); + activity.getSupportActionBar().setDisplayHomeAsUpEnabled(true); + activity.getSupportActionBar().setDisplayShowHomeEnabled(true); + toolbar.setTitle("APP SETTINGS"); + fragment = 1; + } + + @Override + public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { + setPreferencesFromResource(R.xml.settings, rootKey); + } + + @Override + public void onResume() { + super.onResume(); + fragment = 1; + } + + @Override + public void onPause() { + super.onPause(); + } + + public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { + sp = sharedPreferences; + } + } + + public static class UserInterfacePreferencesFragment extends PreferenceFragmentCompat + implements OnSharedPreferenceChangeListener { + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + addPreferencesFromResource(R.xml.userinterface); + sp = getPreferenceScreen().getSharedPreferences(); + + Toolbar toolbar = (Toolbar) activity.findViewById(R.id.toolbar); + activity.setSupportActionBar(toolbar); + activity.getSupportActionBar().setDisplayHomeAsUpEnabled(true); + activity.getSupportActionBar().setDisplayShowHomeEnabled(true); + toolbar.setTitle("USER INTERFACE"); + fragment = 2; + } + + @Override + public void onCreatePreferences(@Nullable Bundle savedInstanceState, String rootKey) { + + } + + @Override + public void onResume() { + super.onResume(); + fragment = 2; + } + + @Override + public void onPause() { + super.onPause(); + } + + public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { + sp = sharedPreferences; + } + + } + public static class QemuPreferencesFragment extends PreferenceFragmentCompat + implements Preference.OnPreferenceChangeListener { + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + addPreferencesFromResource(R.xml.qemu); + sp = getPreferenceScreen().getSharedPreferences(); + + Toolbar toolbar = (Toolbar) activity.findViewById(R.id.toolbar); + activity.setSupportActionBar(toolbar); + activity.getSupportActionBar().setDisplayHomeAsUpEnabled(true); + activity.getSupportActionBar().setDisplayShowHomeEnabled(true); + toolbar.setTitle("QEMU"); + fragment = 3; + } + + @Override + public void onCreatePreferences(@Nullable Bundle savedInstanceState, String rootKey) { + + } + + @Override + public void onResume() { + super.onResume(); + onMemory(); + fragment = 3; + } + + private void onMemory() { + //findPreference("memory").setEnabled(getCusRam(activity)); + } + + @Override + public void onPause() { + super.onPause(); + onMemory(); + } + + @Override + public boolean onPreferenceChange(@NonNull Preference preference, Object newValue) { + onMemory(); + return true; + } + } + public static class VncPreferencesFragment extends PreferenceFragmentCompat + implements OnSharedPreferenceChangeListener { + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + addPreferencesFromResource(R.xml.vnc); + sp = getPreferenceScreen().getSharedPreferences(); + + Toolbar toolbar = (Toolbar) activity.findViewById(R.id.toolbar); + activity.setSupportActionBar(toolbar); + activity.getSupportActionBar().setDisplayHomeAsUpEnabled(true); + activity.getSupportActionBar().setDisplayShowHomeEnabled(true); + toolbar.setTitle("VNC"); + fragment = 4; + } + + @Override + public void onCreatePreferences(@Nullable Bundle savedInstanceState, String rootKey) { + + } + + @Override + public void onResume() { + super.onResume(); + fragment = 4; + } + + @Override + public void onPause() { + super.onPause(); + } + + public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { + sp = sharedPreferences; + } + + } + static String getDNSServer(Activity activity) { + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity); + return prefs.getString("dnsServer", Config.defaultDNSServer); + } + + public static void setDNSServer(Activity activity, String dnsServer) { + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity); + SharedPreferences.Editor edit = prefs.edit(); + edit.putString("dnsServer", dnsServer); + edit.apply(); + } + + public static boolean getVncExternal(Activity activity) { + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity); + return prefs.getBoolean("vncExternal", false); + } + + public static void setVncExternal(Activity activity, boolean vncExternal) { + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity); + SharedPreferences.Editor edit = prefs.edit(); + edit.putBoolean("vncExternal", vncExternal); + edit.apply(); + } + + public static int getOrientationSetting(Activity activity) { + + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity); + int orientation = prefs.getInt("orientation", 0); + // UIUtils.log("Getting First time: " + firstTime); + return orientation; + } + + public static void setOrientationSetting(Activity activity, int orientation) { + + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity); + SharedPreferences.Editor edit = prefs.edit(); + edit.putInt("orientation", orientation); + edit.apply(); + } + + + public static boolean getPromptUpdateVersion(Activity activity) { + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity); + return prefs.getBoolean("updateVersionPrompt", Config.defaultCheckNewVersion); + } + + + public static void setPromptUpdateVersion(Activity activity, boolean flag) { + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity); + SharedPreferences.Editor edit = prefs.edit(); + edit.putBoolean("updateVersionPrompt", flag); + edit.apply(); + // UIUtils.log("Setting First time: "); + } + + static boolean getPrio(Activity activity) { + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity); + return prefs.getBoolean("HighPrio", false); + } + + public static void setPrio(Activity activity, boolean flag) { + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity); + SharedPreferences.Editor edit = prefs.edit(); + edit.putBoolean("HighPrio", flag); + edit.apply(); + // UIUtils.log("Setting First time: "); + } + + public static boolean getAlwaysShowMenuToolbar(Activity activity) { + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity); + return prefs.getBoolean("AlwaysShowMenuToolbar", false); + } + + public static void setAlwaysShowMenuToolbar(Activity activity, boolean flag) { + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity); + SharedPreferences.Editor edit = prefs.edit(); + edit.putBoolean("AlwaysShowMenuToolbar", flag); + edit.apply(); + // UIUtils.log("Setting First time: "); + } + + public static boolean getFullscreen(Activity activity) { + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity); + return prefs.getBoolean("ShowFullscreen", true); + } + + public static void setFullscreen(Activity activity, boolean flag) { + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity); + SharedPreferences.Editor edit = prefs.edit(); + edit.putBoolean("ShowFullscreen", flag); + edit.apply(); + // UIUtils.log("Setting First time: "); + } + + public static boolean getDesktopMode(Activity activity) { + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity); + return prefs.getBoolean("DesktopMode", false); + } + + public static void setDesktopMode(Activity activity, boolean flag) { + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity); + SharedPreferences.Editor edit = prefs.edit(); + edit.putBoolean("DesktopMode", flag); + edit.apply(); + // UIUtils.log("Setting First time: "); + } + + public static boolean getEnableLegacyFileManager(Activity activity) { + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity); + return prefs.getBoolean("EnableLegacyFileManager", false); + } + + + public static void setEnableLegacyFileManager(Activity activity, boolean flag) { + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity); + SharedPreferences.Editor edit = prefs.edit(); + edit.putBoolean("EnableLegacyFileManager", flag); + edit.apply(); + // UIUtils.log("Setting First time: "); + } + + public static String getLastDir(Context context) { + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); + String imagesDir = prefs.getString("lastDir", null); + return imagesDir; + } + + public static void setLastDir(Context context, String imagesPath) { + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); + SharedPreferences.Editor edit = prefs.edit(); + edit.putString("lastDir", imagesPath); + edit.commit(); + } + + public static String getImagesDir(Context context) { + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); + String imagesDir = prefs.getString("imagesDir", null); + return imagesDir; + } + + public static void setImagesDir(Context context, String imagesPath) { + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); + SharedPreferences.Editor edit = prefs.edit(); + edit.putString("imagesDir", imagesPath); + edit.commit(); + } + + + public static String getExportDir(Context context) { + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); + String imagesDir = prefs.getString("exportDir", null); + return imagesDir; + } + + public static void setExportDir(Context context, String imagesPath) { + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); + SharedPreferences.Editor edit = prefs.edit(); + edit.putString("exportDir", imagesPath); + edit.commit(); + } + + + public static String getSharedDir(Context context) { + String lastDir = Environment.getExternalStorageDirectory().getPath(); + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); + return prefs.getString("sharedDir", lastDir); + } + + public static void setSharedDir(Context context, String lastDir) { + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); + SharedPreferences.Editor edit = prefs.edit(); + edit.putString("sharedDir", lastDir); + edit.apply(); + // UIUtils.log("Setting First time: "); + } + + + public static Boolean getMTTCG(Context context) { + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); + Boolean MTTCG = prefs.getBoolean("MTTCG", true); + return MTTCG; + } + + public static void setMTTCG(Context context, Boolean MTTCG) { + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); + SharedPreferences.Editor edit = prefs.edit(); + edit.putBoolean("MTTCG", MTTCG); + edit.commit(); + } + + public static int getCpuCores(Context context) { + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); + int cpuCores = prefs.getInt("cpuCores", 1); + return cpuCores; + } + + public static void setCpuCores(Context context, int cpuCores) { + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); + SharedPreferences.Editor edit = prefs.edit(); + edit.putInt("cpuCores", cpuCores); + edit.commit(); + } + + public static int getExitCode(Context context) { + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); + int exitCode = prefs.getInt("exitCode", 1); + return exitCode; + } + + public static void setExitCode(Context context, int exitCode) { + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); + SharedPreferences.Editor edit = prefs.edit(); + edit.putInt("exitCode", exitCode); + edit.commit(); + } + + public static int getCpuNum(Context context) { + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); + int cpuNum = Integer.parseInt(prefs.getString("cpuNum", "1")); + return cpuNum; + } + + public static void setCpuNum(Context context, String cpuNum) { + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); + SharedPreferences.Editor edit = prefs.edit(); + edit.putString("cpuNum", cpuNum); + edit.commit(); + } + + public static String getControlMode(Context context) { + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); + String controlMode = prefs.getString("controlMode", "D"); + return controlMode; + } + + public static void setControlMode(Context context, String controlMode) { + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); + SharedPreferences.Editor edit = prefs.edit(); + edit.putString("controlMode", controlMode); + edit.commit(); + } + + + public static void setModeNight(Context context, Boolean nightMode) { + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); + SharedPreferences.Editor edit = prefs.edit(); + edit.putBoolean("modeNight", nightMode); + edit.commit(); + } + + public static Boolean getModeNight(Context context) { + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); + return prefs.getBoolean("modeNight", false); + } + + public static void setCusRam(Activity activity, Boolean cusRam) { + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity); + SharedPreferences.Editor edit = prefs.edit(); + edit.putBoolean("customMemory", cusRam); + edit.apply(); + } + + public static boolean getCusRam(Activity activity) { + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity); + return prefs.getBoolean("customMemory", false); + } + + public static boolean isFirstLaunch(Activity activity) { + PackageInfo pInfo = null; + + try { + pInfo = activity.getPackageManager().getPackageInfo(activity.getClass().getPackage().getName(), + PackageManager.GET_META_DATA); + } catch (PackageManager.NameNotFoundException e) { + e.printStackTrace(); + } + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity); + boolean firstTime = prefs.getBoolean("firstTime" + pInfo.versionName, true); + return firstTime; + } + + public static void setFirstLaunch(Activity activity) { + PackageInfo pInfo = null; + + try { + pInfo = activity.getPackageManager().getPackageInfo(activity.getClass().getPackage().getName(), + PackageManager.GET_META_DATA); + } catch (PackageManager.NameNotFoundException e) { + e.printStackTrace(); + } + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity); + SharedPreferences.Editor edit = prefs.edit(); + edit.putBoolean("firstTime" + pInfo.versionName, false); + edit.commit(); + } + + @Override + public void onBackPressed() { + if (fragment == 0) { + finish(); + super.onBackPressed(); + } else { + MainFragment.mainFragment(); + } + } + +} diff --git a/app/src/main/java/com/vectras/qemu/MainVNCActivity.java b/app/src/main/java/com/vectras/qemu/MainVNCActivity.java new file mode 100644 index 0000000..5ad8e27 --- /dev/null +++ b/app/src/main/java/com/vectras/qemu/MainVNCActivity.java @@ -0,0 +1,1331 @@ +package com.vectras.qemu; + +import android.androidVNC.AbstractScaling; +import android.androidVNC.VncCanvasActivity; + +import androidx.appcompat.app.ActionBar; +import androidx.appcompat.app.AppCompatDelegate; +import androidx.appcompat.widget.Toolbar; +import androidx.core.view.MenuItemCompat; +import androidx.fragment.app.FragmentTransaction; + +import android.annotation.SuppressLint; +import android.app.Activity; +import android.app.AlertDialog; +import android.app.Dialog; +import android.app.ProgressDialog; +import android.content.DialogInterface; +import android.content.pm.ActivityInfo; +import android.content.res.Configuration; +import android.graphics.Point; +import android.graphics.drawable.ColorDrawable; +import android.graphics.drawable.Drawable; +import android.os.AsyncTask; +import android.os.Bundle; +import android.os.Handler; +import android.os.Looper; +import android.os.SystemClock; +import android.util.Log; +import android.view.Display; +import android.view.Gravity; +import android.view.KeyEvent; +import android.view.Menu; +import android.view.MenuItem; +import android.view.MotionEvent; +import android.view.View; +import android.view.ViewGroup; +import android.view.Window; +import android.view.WindowManager; +import android.view.inputmethod.BaseInputConnection; +import android.widget.AdapterView; +import android.widget.ArrayAdapter; +import android.widget.Button; +import android.widget.EditText; +import android.widget.ImageButton; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.ListView; +import android.widget.RelativeLayout; +import android.widget.ScrollView; +import android.widget.SeekBar; +import android.widget.SeekBar.OnSeekBarChangeListener; +import android.widget.TextView; + +import com.vectras.vm.Fragment.ControlersOptionsFragment; +import com.vectras.vm.R; +import com.vectras.qemu.utils.Machine; +import com.vectras.qemu.utils.QmpClient; +import com.vectras.vm.utils.UIUtils; + +import java.io.File; +import java.util.logging.Level; +import java.util.logging.Logger; + +import org.json.JSONObject; + + +/** + * @author Dev + */ +public class MainVNCActivity extends VncCanvasActivity { + + public static final int KEYBOARD = 10000; + public static final int QUIT = 10001; + public static final int HELP = 10002; + private static boolean monitorMode = false; + private boolean mouseOn = false; + private Object lockTime = new Object(); + private boolean timeQuit = false; + private Thread timeListenerThread; + private ProgressDialog progDialog; + private static boolean firstConnection; + String[] functionsArray = {"F1", "F2", "F3", "F4", + "F5", "F6", "F7", "F8", "F9", "F10", "F11", "F12"}; + + public boolean ctrlClicked = false; + public boolean altClicked = false; + private ImageButton qmpBtn; + + @Override + public void onCreate(Bundle b) { + + if (MainSettingsManager.getFullscreen(this)) + getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, + WindowManager.LayoutParams.FLAG_FULLSCREEN); + + super.onCreate(b); + + this.vncCanvas.setFocusableInTouchMode(true); + + setDefaulViewMode(); + +// setUIModeMobile(); + + Toolbar mainToolbar = (Toolbar) findViewById(R.id.toolbar); + setSupportActionBar(mainToolbar); + + View decorView = getWindow().getDecorView(); + int uiOptions = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY; + decorView.setSystemUiVisibility(uiOptions); + + onFitToScreen(); + + ImageButton shutdownBtn = findViewById(R.id.shutdownBtn); + ImageButton settingBtn = findViewById(R.id.btnSettings); + ImageButton keyboardBtn = findViewById(R.id.kbdBtn); + ImageButton controllersBtn = findViewById(R.id.btnMode); + ImageButton upBtn = findViewById(R.id.upBtn); + ImageButton leftBtn = findViewById(R.id.leftBtn); + ImageButton downBtn = findViewById(R.id.downBtn); + ImageButton rightBtn = findViewById(R.id.rightBtn); + ImageButton enterBtn = findViewById(R.id.enterBtn); + ImageButton escBtn = findViewById(R.id.escBtn); + ImageButton ctrlBtn = findViewById(R.id.ctrlBtn); + ImageButton altBtn = findViewById(R.id.altBtn); + ImageButton delBtn = findViewById(R.id.delBtn); + Button ctrlAltDelBtn = findViewById(R.id.ctrlAltDelBtn); + qmpBtn = findViewById(R.id.btnQmp); + shutdownBtn.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + Machine.stopVM(activity); + } + }); + keyboardBtn.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + new Handler(Looper.getMainLooper()).postDelayed(new Runnable() { + @Override + public void run() { + toggleKeyboardFlag = UIUtils.onKeyboard(activity, toggleKeyboardFlag, vncCanvas); + } + }, 200); + } + }); + controllersBtn.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); + // Create and show the dialog. + ControlersOptionsFragment newFragment = new ControlersOptionsFragment(); + newFragment.show(ft, "Controllers"); + } + }); + settingBtn.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + final Dialog alertDialog = new Dialog(activity, R.style.MainDialogTheme); + alertDialog.requestWindowFeature(Window.FEATURE_NO_TITLE); + alertDialog.getWindow().setBackgroundDrawable(new ColorDrawable(android.graphics.Color.TRANSPARENT)); + alertDialog.setContentView(R.layout.dialog_setting); + alertDialog.show(); + } + }); + upBtn.setOnTouchListener(new View.OnTouchListener() { + @Override + public boolean onTouch(View v, MotionEvent event) { + if (event.getAction() == MotionEvent.ACTION_DOWN) { + sendKey(KeyEvent.KEYCODE_DPAD_UP, false); + return true; + } else if (event.getAction() == MotionEvent.ACTION_UP) { + sendKey(KeyEvent.KEYCODE_DPAD_UP, true); + return true; + } + return false; + } + }); + leftBtn.setOnTouchListener(new View.OnTouchListener() { + @Override + public boolean onTouch(View v, MotionEvent event) { + if (event.getAction() == MotionEvent.ACTION_DOWN) { + sendKey(KeyEvent.KEYCODE_DPAD_LEFT, false); + return true; + } else if (event.getAction() == MotionEvent.ACTION_UP) { + sendKey(KeyEvent.KEYCODE_DPAD_LEFT, true); + return true; + } + return false; + } + }); + downBtn.setOnTouchListener(new View.OnTouchListener() { + @Override + public boolean onTouch(View v, MotionEvent event) { + if (event.getAction() == MotionEvent.ACTION_DOWN) { + sendKey(KeyEvent.KEYCODE_DPAD_DOWN, false); + return true; + } else if (event.getAction() == MotionEvent.ACTION_UP) { + sendKey(KeyEvent.KEYCODE_DPAD_DOWN, true); + return true; + } + return false; + } + }); + rightBtn.setOnTouchListener(new View.OnTouchListener() { + @Override + public boolean onTouch(View v, MotionEvent event) { + if (event.getAction() == MotionEvent.ACTION_DOWN) { + sendKey(KeyEvent.KEYCODE_DPAD_RIGHT, false); + return true; + } else if (event.getAction() == MotionEvent.ACTION_UP) { + sendKey(KeyEvent.KEYCODE_DPAD_RIGHT, true); + return true; + } + return false; + } + }); + escBtn.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + keyDownUp(KeyEvent.KEYCODE_ESCAPE); + } + }); + enterBtn.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + keyDownUp(KeyEvent.KEYCODE_ENTER); + } + }); + ctrlBtn.setOnClickListener(new View.OnClickListener() { + @SuppressLint("UseCompatLoadingForDrawables") + @Override + public void onClick(View v) { + if (!ctrlClicked) { + sendKey(KeyEvent.KEYCODE_CTRL_LEFT, false); + ctrlBtn.setBackground(getResources().getDrawable(R.drawable.controls_button2)); + ctrlClicked = true; + } else { + sendKey(KeyEvent.KEYCODE_CTRL_LEFT, true); + ctrlBtn.setBackground(getResources().getDrawable(R.drawable.controls_button1)); + ctrlClicked = false; + } + } + }); + altBtn.setOnClickListener(new View.OnClickListener() { + @SuppressLint("UseCompatLoadingForDrawables") + @Override + public void onClick(View v) { + if (!altClicked) { + sendKey(KeyEvent.KEYCODE_ALT_LEFT, false); + altBtn.setBackground(getResources().getDrawable(R.drawable.controls_button2)); + altClicked = true; + } else { + sendKey(KeyEvent.KEYCODE_ALT_LEFT, true); + altBtn.setBackground(getResources().getDrawable(R.drawable.controls_button1)); + altClicked = false; + } + } + }); + delBtn.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + keyDownUp(KeyEvent.KEYCODE_DEL); + } + }); + ctrlAltDelBtn.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + sendCtrlAtlDelKey(); + } + }); + qmpBtn.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if (monitorMode) { + onVNC(); + qmpBtn.setImageDrawable(getResources().getDrawable(R.drawable.round_terminal_24)); + } else { + onMonitor(); + qmpBtn.setImageDrawable(getResources().getDrawable(R.drawable.round_computer_24)); + } + } + }); + if (monitorMode) { + qmpBtn.setImageDrawable(getResources().getDrawable(R.drawable.round_terminal_24)); + } else { + qmpBtn.setImageDrawable(getResources().getDrawable(R.drawable.round_computer_24)); + } + + ArrayAdapter adapter = new ArrayAdapter<>(this, + R.layout.container_function, functionsArray); + + ListView listView = findViewById(R.id.functions); + listView.setAdapter(adapter); + listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + if (position == 0) { + keyDownUp(KeyEvent.KEYCODE_F1); + } else if (position == 1) { + keyDownUp(KeyEvent.KEYCODE_F2); + } else if (position == 2) { + keyDownUp(KeyEvent.KEYCODE_F3); + } else if (position == 3) { + keyDownUp(KeyEvent.KEYCODE_F4); + } else if (position == 4) { + keyDownUp(KeyEvent.KEYCODE_F5); + } else if (position == 5) { + keyDownUp(KeyEvent.KEYCODE_F6); + } else if (position == 6) { + keyDownUp(KeyEvent.KEYCODE_F7); + } else if (position == 7) { + keyDownUp(KeyEvent.KEYCODE_F8); + } else if (position == 8) { + keyDownUp(KeyEvent.KEYCODE_F9); + } else if (position == 9) { + keyDownUp(KeyEvent.KEYCODE_F10); + } else if (position == 10) { + keyDownUp(KeyEvent.KEYCODE_F11); + } else if (position == 11) { + keyDownUp(KeyEvent.KEYCODE_F12); + } + } + }); + } + + private void keyDownUp(int keyEventCode) { + dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, keyEventCode)); + dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, keyEventCode)); + } + + private void sendKey(int keyEventCode, boolean up) { + if (up) + dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, keyEventCode)); + else dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, keyEventCode)); + } + + public void sendCtrlAtlDelKey() { + dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_CTRL_LEFT)); + try { + Thread.sleep(100); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_ALT_LEFT)); + try { + Thread.sleep(100); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DEL)); + try { + Thread.sleep(100); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_CTRL_LEFT)); + dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_ALT_LEFT)); + dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_DEL)); + } + + private void setDefaulViewMode() { + + + // Fit to Screen + AbstractScaling.getById(R.id.itemFitToScreen).setScaleTypeForActivity(this); + showPanningState(); + +// screenMode = VNCScreenMode.FitToScreen; + setLayout(getResources().getConfiguration()); + + UIUtils.setOrientation(this); + } + + @Override + public void onConfigurationChanged(Configuration newConfig) { + super.onConfigurationChanged(newConfig); + setLayout(newConfig); + } + + public enum VNCScreenMode { + Normal, + FitToScreen, + Fullscreen //fullscreen not implemented yet + } + + public static VNCScreenMode screenMode = VNCScreenMode.FitToScreen; + + private void setLayout(Configuration newConfig) { + + boolean isLanscape = + (newConfig != null && newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) + || UIUtils.isLandscapeOrientation(this); + + View vnc_canvas_layout = (View) this.findViewById(R.id.vnc_canvas_layout); + RelativeLayout.LayoutParams vnc_canvas_layout_params = null; + RelativeLayout.LayoutParams vnc_params = null; + //normal 1-1 + if (screenMode == VNCScreenMode.Normal) { + if (isLanscape) { + vnc_params = new RelativeLayout.LayoutParams( + ViewGroup.LayoutParams.WRAP_CONTENT, + ViewGroup.LayoutParams.WRAP_CONTENT + ); +// vnc_params.addRule(RelativeLayout.CENTER_IN_PARENT); + vnc_params.addRule(RelativeLayout.CENTER_HORIZONTAL); + vnc_params.addRule(RelativeLayout.ALIGN_PARENT_TOP); + + vnc_canvas_layout_params = new RelativeLayout.LayoutParams( + ViewGroup.LayoutParams.WRAP_CONTENT, + ViewGroup.LayoutParams.WRAP_CONTENT + ); +// vnc_canvas_layout_params.addRule(RelativeLayout.CENTER_IN_PARENT); + vnc_canvas_layout_params.addRule(RelativeLayout.CENTER_HORIZONTAL); + vnc_canvas_layout_params.addRule(RelativeLayout.ALIGN_PARENT_TOP); + + } else { + vnc_params = new RelativeLayout.LayoutParams( + ViewGroup.LayoutParams.WRAP_CONTENT, + ViewGroup.LayoutParams.WRAP_CONTENT + ); + vnc_params.addRule(RelativeLayout.CENTER_HORIZONTAL); + vnc_params.addRule(RelativeLayout.ALIGN_PARENT_TOP); + + vnc_canvas_layout_params = new RelativeLayout.LayoutParams( + ViewGroup.LayoutParams.WRAP_CONTENT, + ViewGroup.LayoutParams.WRAP_CONTENT + ); + vnc_canvas_layout_params.addRule(RelativeLayout.ALIGN_PARENT_TOP); + vnc_canvas_layout_params.addRule(RelativeLayout.CENTER_HORIZONTAL); + } + } else { + //fittoscreen + if (isLanscape) { + vnc_params = new RelativeLayout.LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.MATCH_PARENT + ); + vnc_params.addRule(RelativeLayout.CENTER_IN_PARENT); + vnc_canvas_layout_params = new RelativeLayout.LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.MATCH_PARENT + ); + vnc_canvas_layout_params.addRule(RelativeLayout.CENTER_IN_PARENT); + } else { + final Display display = getWindow().getWindowManager().getDefaultDisplay(); + Point size = new Point(); + display.getSize(size); + + int h = ViewGroup.LayoutParams.WRAP_CONTENT; + if (vncCanvas != null && vncCanvas.rfb != null + && vncCanvas.rfb.framebufferWidth != 0 + && vncCanvas.rfb.framebufferHeight != 0) { + h = size.x * vncCanvas.rfb.framebufferHeight / vncCanvas.rfb.framebufferWidth; + } + vnc_params = new RelativeLayout.LayoutParams( + size.x, + h + ); + vnc_params.addRule(RelativeLayout.CENTER_HORIZONTAL); + vnc_params.addRule(RelativeLayout.ALIGN_PARENT_TOP); + + vnc_canvas_layout_params = new RelativeLayout.LayoutParams( + ViewGroup.LayoutParams.WRAP_CONTENT, + ViewGroup.LayoutParams.WRAP_CONTENT + ); + vnc_canvas_layout_params.addRule(RelativeLayout.ALIGN_PARENT_TOP); + vnc_canvas_layout_params.addRule(RelativeLayout.CENTER_HORIZONTAL); + } + } + this.vncCanvas.setLayoutParams(vnc_params); + vnc_canvas_layout.setLayoutParams(vnc_canvas_layout_params); + + this.invalidateOptionsMenu(); + } + + public void stopTimeListener() { + Log.v(TAG, "Stopping Listener"); + synchronized (this.lockTime) { + this.timeQuit = true; + this.lockTime.notifyAll(); + } + } + + public void onDestroy() { + super.onDestroy(); + this.stopTimeListener(); + + } + + public void onPause() { + MainService.updateServiceNotification("Vectras VM Running in Background"); + super.onPause(); + } + + public void onResume() { + MainService.updateServiceNotification("Vectras VM Running"); + if (monitorMode) { + qmpBtn.setImageDrawable(getResources().getDrawable(R.drawable.round_terminal_24)); + } else { + qmpBtn.setImageDrawable(getResources().getDrawable(R.drawable.round_computer_24)); + } + super.onResume(); + } + + public void checkStatus() { + while (timeQuit != true) { + MainActivityCommon.VMStatus status = Machine.checkSaveVMStatus(activity); + Log.v(TAG, "Status: " + status); + if (status == MainActivityCommon.VMStatus.Unknown + || status == MainActivityCommon.VMStatus.Completed + || status == MainActivityCommon.VMStatus.Failed + ) { + //Log.v(TAG, "Saving state is done: " + status); + stopTimeListener(); + return; + } + try { + Thread.sleep(1000); + } catch (InterruptedException ex) { + Log.w("SaveVM", "Interrupted"); + } + } + Log.v("SaveVM", "Save state complete"); + + } + + public void startSaveVMListener() { + this.stopTimeListener(); + timeQuit = false; + try { + Log.v("Listener", "Time Listener Started..."); + checkStatus(); + synchronized (lockTime) { + while (timeQuit == false) { + lockTime.wait(); + } + lockTime.notifyAll(); + } + } catch (Exception ex) { + ex.printStackTrace(); + Log.v("SaveVM", "Time listener thread error: " + ex.getMessage()); + } + Log.v("Listener", "Time listener thread exited..."); + + } + + String TAG = "MainVNCActivity"; + + @Override + public boolean onOptionsItemSelected(final MenuItem item) { + super.onOptionsItemSelected(item); + if (item.getItemId() == this.KEYBOARD || item.getItemId() == R.id.itemKeyboard) { + new Handler(Looper.getMainLooper()).postDelayed(new Runnable() { + @Override + public void run() { + toggleKeyboardFlag = UIUtils.onKeyboard(activity, toggleKeyboardFlag, vncCanvas); + } + }, 200); + } else if (item.getItemId() == R.id.itemReset) { + Machine.resetVM(activity); + } else if (item.getItemId() == R.id.itemShutdown) { + UIUtils.hideKeyboard(this, vncCanvas); + Machine.stopVM(activity); + } else if (item.getItemId() == R.id.itemDrives) { + + } else if (item.getItemId() == R.id.itemMonitor) { + if (this.monitorMode) { + this.onVNC(); + } else { + this.onMonitor(); + } + } else if (item.getItemId() == R.id.itemSaveState) { + this.promptPause(activity); + } else if (item.getItemId() == R.id.itemFitToScreen) { + return onFitToScreen(); + } else if (item.getItemId() == R.id.itemFullScreen) { + return toggleFullScreen(); + } else if (item.getItemId() == this.QUIT) { + } else if (item.getItemId() == R.id.itemCenterMouse) { + onMouseMode(); + } else if (item.getItemId() == R.id.itemCalibrateMouse) { + calibration(); + } else if (item.getItemId() == R.id.itemHelp) { + + } else if (item.getItemId() == R.id.itemHideToolbar) { + this.onHideToolbar(); + } else if (item.getItemId() == R.id.itemDisplay) { + this.onSelectMenuVNCDisplay(); + } else if (item.getItemId() == R.id.itemViewLog) { + + } + + this.invalidateOptionsMenu(); + + return true; + } + + private void onMouseMode() { + + String[] items = {"Trackpad Mouse (Phone)", + "Bluetooth/USB Mouse (Desktop mode)", //Physical mouse for Chromebook, Android x86 PC, or Bluetooth Mouse + }; + final AlertDialog.Builder mBuilder = new AlertDialog.Builder(this); + mBuilder.setTitle("Mouse"); + mBuilder.setSingleChoiceItems(items, Config.mouseMode.ordinal(), new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int i) { + switch (i) { + case 0: + setUIModeMobile(true); + break; + case 1: + promptSetUIModeDesktop(MainVNCActivity.this, false); + break; + default: + break; + } + dialog.dismiss(); + } + }); + final AlertDialog alertDialog = mBuilder.create(); + alertDialog.show(); + + } + + public boolean checkVMResolutionFits() { + if (vncCanvas.rfb.framebufferWidth < vncCanvas.getWidth() + && vncCanvas.rfb.framebufferHeight < vncCanvas.getHeight()) + return true; + + return false; + } + + private void onDisplayMode() { + + String[] items = { + "Normal (One-To-One)", + "Fit To Screen" + //"Full Screen" //Stretched + }; + int currentScaleType = vncCanvas.getScaleType() == ImageView.ScaleType.FIT_CENTER ? 1 : 0; + + final AlertDialog.Builder mBuilder = new AlertDialog.Builder(this); + mBuilder.setTitle("Display Mode"); + mBuilder.setSingleChoiceItems(items, currentScaleType, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int i) { + switch (i) { + case 0: + onNormalScreen(); + onMouse(); + break; + case 1: + if (Config.mouseMode == Config.MouseMode.External) { + UIUtils.toastShort(MainVNCActivity.this, "Fit to Screen disabled under Desktop mode"); + dialog.dismiss(); + return; + } + onFitToScreen(); + onMouse(); + break; + default: + break; + } + dialog.dismiss(); + } + }); + final AlertDialog alertDialog = mBuilder.create(); + alertDialog.show(); + + } + + private void setUIModeMobile(boolean fitToScreen) { + + try { + MotionEvent a = MotionEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, 0, 0, 0); + + Config.mouseMode = Config.MouseMode.Trackpad; + MainSettingsManager.setDesktopMode(this, false); + if (fitToScreen) + onFitToScreen(); + else + onNormalScreen(); + onMouse(); + + //UIUtils.toastShort(MainVNCActivity.this, "Trackpad Calibrating"); + invalidateOptionsMenu(); + } catch (Exception ex) { + if (Config.debug) + ex.printStackTrace(); + } + } + + private void promptSetUIModeDesktop(final Activity activity, final boolean mouseMethodAlt) { + + + final AlertDialog alertDialog; + alertDialog = new AlertDialog.Builder(activity, R.style.MainDialogTheme).create(); + alertDialog.setTitle("Desktop mode"); + + LinearLayout mLayout = new LinearLayout(this); + mLayout.setPadding(20, 20, 20, 20); + mLayout.setOrientation(LinearLayout.VERTICAL); + + TextView textView = new TextView(activity); + textView.setVisibility(View.VISIBLE); + + String desktopInstructions = this.getString(R.string.desktopInstructions); + if (!checkVMResolutionFits()) { + String resolutionWarning = "Warning: Machine resolution " + + vncCanvas.rfb.framebufferWidth + "x" + vncCanvas.rfb.framebufferHeight + + " is too high for Desktop Mode. " + + "Scaling will be used and Mouse Alignment will not be accurate. " + + "Reduce display resolution for better experience\n\n"; + desktopInstructions = resolutionWarning + desktopInstructions; + } + textView.setText(desktopInstructions); + + LinearLayout.LayoutParams textViewParams = new LinearLayout.LayoutParams( + LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT); + ScrollView scrollView = new ScrollView(this); + scrollView.addView(textView); + mLayout.addView(scrollView, textViewParams); + alertDialog.setView(mLayout); + + alertDialog.setButton(DialogInterface.BUTTON_POSITIVE, "OK", new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int which) { + + setUIModeDesktop(); + alertDialog.dismiss(); + } + }); + alertDialog.setButton(DialogInterface.BUTTON_NEGATIVE, "Cancel", new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int which) { + alertDialog.dismiss(); + } + }); + alertDialog.show(); + + } + + private void setUIModeDesktop() { + + try { + MotionEvent a = MotionEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, 0, 0, 0); + Config.mouseMode = Config.MouseMode.External; + MainSettingsManager.setDesktopMode(this, true); + if (Config.showToast) + UIUtils.toastShort(MainVNCActivity.this, "External Mouse Enabled"); + onNormalScreen(); + AbstractScaling.getById(R.id.itemOneToOne).setScaleTypeForActivity(MainVNCActivity.this); + showPanningState(); + + onMouse(); + } catch (Exception e) { + if (Config.debug) + e.printStackTrace(); + } + //vncCanvas.reSize(false); + invalidateOptionsMenu(); + } + + public void setContentView() { + + setContentView(R.layout.activity_vnc); + + } + + private boolean toggleFullScreen() { + + UIUtils.toastShort(this, "VNC Fullscreen not supported"); + + return false; + } + + private boolean onFitToScreen() { + + try { + UIUtils.setOrientation(this); + ActionBar bar = this.getSupportActionBar(); + if (bar != null && !MainSettingsManager.getAlwaysShowMenuToolbar(this)) { + bar.hide(); + } + + inputHandler = getInputHandlerById(R.id.itemInputTouchpad); + connection.setInputMode(inputHandler.getName()); + connection.setFollowMouse(true); + mouseOn = true; + AbstractScaling.getById(R.id.itemFitToScreen).setScaleTypeForActivity(this); + showPanningState(); + screenMode = VNCScreenMode.FitToScreen; + setLayout(null); + + return true; + } catch (Exception ex) { + if (Config.debug) + ex.printStackTrace(); + } + return false; + } + + private boolean onNormalScreen() { + + try { + //Force only landscape + setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE); + ActionBar bar = MainVNCActivity.this.getSupportActionBar(); + if (bar != null) { + bar.hide(); + } + + inputHandler = getInputHandlerById(R.id.itemInputTouchpad); + connection.setInputMode(inputHandler.getName()); + connection.setFollowMouse(true); + mouseOn = true; + AbstractScaling.getById(R.id.itemOneToOne).setScaleTypeForActivity(this); + showPanningState(); + screenMode = VNCScreenMode.Normal; + setLayout(null); + + return true; + } catch (Exception ex) { + if (Config.debug) + ex.printStackTrace(); + } finally { + + } + return false; + } + + private boolean onMouse() { + + // Main: For now we disable other modes + if (Config.disableMouseModes) + mouseOn = false; + + + if (mouseOn == false) { + inputHandler = getInputHandlerById(R.id.itemInputTouchpad); + connection.setInputMode(inputHandler.getName()); + connection.setFollowMouse(true); + mouseOn = true; + } else { + // XXX: Main + // we disable panning for now + // input1 = getInputHandlerById(R.id.itemFitToScreen); + // input1 = getInputHandlerById(R.id.itemInputTouchPanZoomMouse); + // connection.setFollowMouse(false); + // mouseOn = false; + } + + //Start calibration + calibration(); + + return true; + } + + //XXX: We need to adjust the mouse inside the Guest + // This is a known issue with QEMU under VNC mode + // this only fixes things temporarily. + // There is a workaround to choose USB Tablet for mouse emulation + // though it might not work for all Guest OSes + public void calibration() { + Thread t = new Thread(new Runnable() { + public void run() { + try { + + int origX = vncCanvas.mouseX; + int origY = vncCanvas.mouseY; + MotionEvent event = null; + + for (int i = 0; i < 4 * 20; i++) { + int x = 0 + i * 50; + int y = 0 + i * 50; + if (i % 4 == 1) { + x = vncCanvas.rfb.framebufferWidth; + } else if (i % 4 == 2) { + y = vncCanvas.rfb.framebufferHeight; + } else if (i % 4 == 3) { + x = 0; + } + + event = MotionEvent.obtain(SystemClock.uptimeMillis(), + SystemClock.uptimeMillis(), MotionEvent.ACTION_MOVE, + x, y, 0); + Thread.sleep(10); + vncCanvas.processPointerEvent(event, false, false); + + + } + + Thread.sleep(50); + event = MotionEvent.obtain(SystemClock.uptimeMillis(), + SystemClock.uptimeMillis(), MotionEvent.ACTION_MOVE, + origX, origY, 0); + vncCanvas.processPointerEvent(event, false, false); + + } catch (Exception ex) { + + } + } + }); + t.start(); + } + + @Override + public boolean onPrepareOptionsMenu(Menu menu) { + menu.clear(); + return this.setupMenu(menu); + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + menu.clear(); + return this.setupMenu(menu); + + } + + public boolean setupMenu(Menu menu) { + getMenuInflater().inflate(R.menu.vnccanvasactivitymenu, menu); + + int maxMenuItemsShown = 4; + int actionShow = MenuItemCompat.SHOW_AS_ACTION_IF_ROOM; + if (UIUtils.isLandscapeOrientation(this)) { + maxMenuItemsShown = 6; + actionShow = MenuItemCompat.SHOW_AS_ACTION_ALWAYS; + } + + if (vncCanvas.scaling != null) { + menu.findItem(vncCanvas.scaling.getId()).setChecked(true); + } + + if (this.monitorMode) { + menu.findItem(R.id.itemMonitor).setTitle("VM Display"); + + } else { + menu.findItem(R.id.itemMonitor).setTitle("QEMU Monitor"); + + } + + //XXX: We don't need these for now + menu.removeItem(menu.findItem(R.id.itemEnterText).getItemId()); + menu.removeItem(menu.findItem(R.id.itemSendKeyAgain).getItemId()); + menu.removeItem(menu.findItem(R.id.itemSpecialKeys).getItemId()); + menu.removeItem(menu.findItem(R.id.itemInputMode).getItemId()); + menu.removeItem(menu.findItem(R.id.itemScaling).getItemId()); + menu.removeItem(menu.findItem(R.id.itemCtrlAltDel).getItemId()); + menu.removeItem(menu.findItem(R.id.itemCtrlC).getItemId()); + menu.removeItem(menu.findItem(R.id.itemColorMode).getItemId()); + menu.removeItem(menu.findItem(R.id.itemFullScreen).getItemId()); + + if (MainSettingsManager.getAlwaysShowMenuToolbar(activity) || Config.mouseMode == Config.MouseMode.External) { + menu.removeItem(menu.findItem(R.id.itemHideToolbar).getItemId()); + maxMenuItemsShown--; + } + + // Menu inputMenu = menu.findItem(R.id.itemInputMode).getSubMenu(); + // + // inputModeMenuItems = new MenuItem[inputModeIds.length]; + // for (int i = 0; i < inputModeIds.length; i++) { + // inputModeMenuItems[i] = inputMenu.findItem(inputModeIds[i]); + // } + // updateInputMenu(); + // menu.removeItem(menu.findItem(R.id.itemCenterMouse).getItemId()); + + // Main: Disable Panning for now + // if (this.mouseOn) { + // menu.findItem(R.id.itemCenterMouse).setTitle("Pan (Mouse Off)"); + // menu.findItem(R.id.itemCenterMouse).setIcon(R.drawable.pan); + // } else { + menu.findItem(R.id.itemCenterMouse).setTitle("Mouse"); + // + // } + + + for (int i = 0; i < menu.size() && i < maxMenuItemsShown; i++) { + MenuItemCompat.setShowAsAction(menu.getItem(i), actionShow); + } + + return true; + + } + + + public static boolean toggleKeyboardFlag = true; + + private void onMonitor() { + if (Config.showToast) + UIUtils.toastShort(this, "Connecting to QEMU Monitor"); + + Thread t = new Thread(new Runnable() { + public void run() { + try { + Thread.sleep(500); + } catch (InterruptedException e) { + e.printStackTrace(); + } + monitorMode = true; + vncCanvas.sendMetaKey1(50, 6); + + } + }); + t.start(); + } + + private void onVNC() { + UIUtils.toastShort(this, "Connecting to VM"); + + Thread t = new Thread(new Runnable() { + public void run() { + try { + Thread.sleep(500); + } catch (InterruptedException e) { + e.printStackTrace(); + } + monitorMode = false; + vncCanvas.sendMetaKey1(49, 6); + } + }); + t.start(); + + + } + + // FIXME: We need this to able to catch complex characters strings like + // grave and send it as text + @Override + public boolean dispatchKeyEvent(KeyEvent event) { + if (event.getAction() == KeyEvent.ACTION_MULTIPLE && event.getKeyCode() == KeyEvent.KEYCODE_UNKNOWN) { + vncCanvas.sendText(event.getCharacters().toString()); + return true; + } else + return super.dispatchKeyEvent(event); + + } + + private void resumeVM() { + if (MainActivityCommon.vmexecutor == null) { + return; + } + Thread t = new Thread(new Runnable() { + public void run() { + if (MainActivityCommon.vmexecutor.paused == 1) { + try { + Thread.sleep(4000); + } catch (InterruptedException ex) { + Logger.getLogger(MainVNCActivity.class.getName()).log(Level.SEVERE, null, ex); + } + if (vncCanvas == null) + return; + + MainActivityCommon.vmexecutor.paused = 0; + String command = QmpClient.cont(); + String msg = QmpClient.sendCommand(command); + new Handler(Looper.getMainLooper()).postDelayed(new Runnable() { + @Override + public void run() { + setUIModeMobile(screenMode == VNCScreenMode.FitToScreen); + } + }, 500); + + } + } + }); + t.start(); + + } + + private void onPauseVM() { + Thread t = new Thread(new Runnable() { + public void run() { + // Delete any previous state file + if (MainActivityCommon.vmexecutor.save_state_name != null) { + File file = new File(MainActivityCommon.vmexecutor.save_state_name); + if (file.exists()) { + file.delete(); + } + } + + UIUtils.toastShort(getApplicationContext(), "Please wait while saving VM State"); + + String uri = "fd:" + MainActivityCommon.vmexecutor.get_fd(MainActivityCommon.vmexecutor.save_state_name); + String command = QmpClient.stop(); + String msg = QmpClient.sendCommand(command); +// if (msg != null) +// Log.i(TAG, msg); + command = QmpClient.migrate(false, false, uri); + msg = QmpClient.sendCommand(command); + if (msg != null) { +// Log.i(TAG, msg); + processMigrationResponse(msg); + } + + new Handler(Looper.getMainLooper()).postDelayed(new Runnable() { + @Override + public void run() { + VMListener a = new VMListener(); + a.execute(); + } + }, 0); + } + }); + t.start(); + + } + + private void processMigrationResponse(String response) { + String errorStr = null; + + if (response.contains("error")) { + try { + JSONObject object = new JSONObject(response); + errorStr = object.getString("error"); + } catch (Exception ex) { + if (Config.debug) + ex.printStackTrace(); + } + } + if (errorStr != null && errorStr.contains("desc")) { + String descStr = null; + + try { + JSONObject descObj = new JSONObject(errorStr); + descStr = descObj.getString("desc"); + } catch (Exception ex) { + if (Config.debug) + ex.printStackTrace(); + } + final String descStr1 = descStr; + + new Handler(Looper.getMainLooper()).postDelayed(new Runnable() { + @Override + public void run() { + Machine.pausedErrorVM(activity, descStr1); + } + }, 100); + + } + + } + + + private class VMListener extends AsyncTask { + + @Override + protected Void doInBackground(Void... arg0) { + startSaveVMListener(); + return null; + } + + @Override + protected void onPostExecute(Void test) { + // if (progDialog.isShowing()) { + // progDialog.dismiss(); + // } + + } + } + + private void fullScreen() { + AbstractScaling.getById(R.id.itemFitToScreen).setScaleTypeForActivity(this); + showPanningState(); + } + + public void promptPause(final Activity activity) { + final AlertDialog alertDialog; + alertDialog = new AlertDialog.Builder(activity, R.style.MainDialogTheme).create(); + alertDialog.setTitle("Pause VM"); + TextView stateView = new TextView(activity); + stateView.setText("This make take a while depending on the RAM size used"); + stateView.setPadding(20, 20, 20, 20); + alertDialog.setView(stateView); + + alertDialog.setButton(DialogInterface.BUTTON_POSITIVE, "Pause", new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int which) { + onPauseVM(); + return; + } + }); + alertDialog.show(); + + } + + public void onBackPressed() { + + // super.onBackPressed(); + if (!MainSettingsManager.getAlwaysShowMenuToolbar(activity)) { + ActionBar bar = this.getSupportActionBar(); + if (bar != null) { + if (bar.isShowing() && Config.mouseMode == Config.MouseMode.Trackpad) { + bar.hide(); + }/* else + bar.show();*/ + } + } else + super.onBackPressed(); + + } + + public void onHideToolbar() { + ActionBar bar = this.getSupportActionBar(); + if (bar != null) { + bar.hide(); + } + } + + @Override + public void onConnected() { + this.resumeVM(); + if (!firstConnection) + UIUtils.showHints(this); + firstConnection = true; + + new Handler(Looper.getMainLooper()).postDelayed(new Runnable() { + @Override + public void run() { + + if (Config.mouseMode == Config.MouseMode.External) + setUIModeDesktop(); + else + setUIModeMobile(screenMode == VNCScreenMode.FitToScreen); + } + }, 1000); + + } + + public void onSelectMenuVNCDisplay() { + + final AlertDialog alertDialog; + alertDialog = new AlertDialog.Builder(activity, R.style.MainDialogTheme).create(); + alertDialog.setTitle("Display"); + + LinearLayout.LayoutParams volParams = new LinearLayout.LayoutParams( + LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT); + + LinearLayout t = createVNCDisplayPanel(); + t.setLayoutParams(volParams); + + ScrollView s = new ScrollView(activity); + s.addView(t); + alertDialog.setView(s); + alertDialog.setButton(Dialog.BUTTON_POSITIVE, "OK", new DialogInterface.OnClickListener() { + + public void onClick(DialogInterface dialog, int which) { + alertDialog.cancel(); + } + }); + alertDialog.show(); + + } + + + public LinearLayout createVNCDisplayPanel() { + LinearLayout layout = new LinearLayout(this); + layout.setOrientation(LinearLayout.VERTICAL); + layout.setPadding(20, 20, 20, 20); + + LinearLayout.LayoutParams params = new LinearLayout.LayoutParams( + LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT); + int currRate = getCurrentVNCRefreshRate(); + + LinearLayout buttonsLayout = new LinearLayout(this); + buttonsLayout.setOrientation(LinearLayout.HORIZONTAL); + buttonsLayout.setGravity(Gravity.CENTER_HORIZONTAL); + Button displayMode = new Button(this); + + displayMode.setText("Display Mode"); + displayMode.setOnClickListener(new View.OnClickListener() { + public void onClick(View view) { + onDisplayMode(); + } + }); + buttonsLayout.addView(displayMode); + + + Button colors = new Button(this); + colors.setText("Color Mode"); + colors.setOnClickListener(new View.OnClickListener() { + public void onClick(View view) { + selectColorModel(); + + } + }); + buttonsLayout.addView(colors); + + layout.addView(buttonsLayout); + + final TextView value = new TextView(this); + value.setText("Display Refresh Rate: " + currRate + " Hz"); + layout.addView(value); + value.setLayoutParams(params); + + SeekBar rate = new SeekBar(this); + rate.setMax(Config.MAX_DISPLAY_REFRESH_RATE); + + rate.setProgress(currRate); + rate.setLayoutParams(params); + + ((SeekBar) rate).setOnSeekBarChangeListener(new OnSeekBarChangeListener() { + + public void onProgressChanged(SeekBar s, int progress, boolean touch) { + value.setText("Refresh Rate: " + (progress + 1) + " Hz"); + } + + public void onStartTrackingTouch(SeekBar arg0) { + + } + + public void onStopTrackingTouch(SeekBar arg0) { + int progress = arg0.getProgress() + 1; + int refreshMs = 1000 / progress; + Log.v(TAG, "Changing display refresh rate (ms): " + refreshMs); + MainActivityCommon.vmexecutor.setvncrefreshrate(refreshMs); + + } + }); + + + layout.addView(rate); + + return layout; + + } + + public int getCurrentVNCRefreshRate() { + return 1000 / MainActivityCommon.vmexecutor.getvncrefreshrate(); + } + +} diff --git a/app/src/main/java/com/vectras/qemu/SettingsFragment.java b/app/src/main/java/com/vectras/qemu/SettingsFragment.java new file mode 100644 index 0000000..13504fe --- /dev/null +++ b/app/src/main/java/com/vectras/qemu/SettingsFragment.java @@ -0,0 +1,100 @@ +package com.vectras.qemu; + +import static android.content.Context.MODE_PRIVATE; + +import android.app.AlarmManager; +import android.app.PendingIntent; +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; +import android.os.Bundle; +import android.os.Handler; + +import androidx.annotation.Nullable; +import androidx.preference.EditTextPreference; +import androidx.preference.Preference; +import androidx.preference.PreferenceFragmentCompat; +import androidx.preference.PreferenceManager; +import androidx.preference.SwitchPreferenceCompat; + +import com.vectras.qemu.utils.Machine; +import com.vectras.vm.R; +import com.vectras.vm.SplashActivity; + +public class SettingsFragment extends PreferenceFragmentCompat { + + private Handler mHandler; + public SharedPreferences mPref; + + @Override + public void onCreatePreferences(@Nullable Bundle savedInstanceState, @Nullable String rootKey) { + setPreferencesFromResource(R.xml.settings, rootKey); + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + mHandler = new Handler(); + SharedPreferences.OnSharedPreferenceChangeListener listener; + listener = new SharedPreferences.OnSharedPreferenceChangeListener() { + public void onSharedPreferenceChanged(SharedPreferences prefs, String key) { + switch (key) { + + case "modeNight": + mHandler.postDelayed(new Runnable() { + @Override + public void run() { + Intent startActivity = new Intent(getContext(), SplashActivity.class); + int pendingIntentId = 123456; + PendingIntent pendingIntent = PendingIntent.getActivity(getContext(), pendingIntentId, startActivity, PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_IMMUTABLE); + + AlarmManager mgr = (AlarmManager) MainSettingsManager.activity.getSystemService(Context.ALARM_SERVICE); + mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 500, pendingIntent); + + System.exit(0); + } + }, 300); + + getActivity().finish(); + break; + case "customMemory": + if (prefs.getBoolean("customMemory", false)) + findPreference("memory").setEnabled(true); + else + findPreference("memory").setEnabled(false); + break; + case "MTTCG": + if (prefs.getBoolean("MTTCG", false)) { + findPreference("cpuNum").setEnabled(false); + MainSettingsManager.setCpuCores(getContext(), 1); + } else { + findPreference("cpuNum").setEnabled(true); + } + break; + } + } + }; + + mPref = getPreferenceManager().getDefaultSharedPreferences(getContext()); + if (mPref != null) { + mPref.registerOnSharedPreferenceChangeListener(listener); + } + } + + @Override + public void onResume() { + super.onResume(); + + if (mPref.getBoolean("customMemory", false)) + findPreference("memory").setEnabled(true); + else + findPreference("memory").setEnabled(false); + + if (mPref.getBoolean("MTTCG", false)) { + findPreference("cpuNum").setEnabled(false); + } else { + findPreference("cpuNum").setEnabled(true); + } + } +} diff --git a/app/src/main/java/com/vectras/qemu/jni/StartVM.java b/app/src/main/java/com/vectras/qemu/jni/StartVM.java new file mode 100644 index 0000000..af63609 --- /dev/null +++ b/app/src/main/java/com/vectras/qemu/jni/StartVM.java @@ -0,0 +1,868 @@ +package com.vectras.qemu.jni; + +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; +import android.util.Log; +import android.view.MotionEvent; + +import com.vectras.qemu.Config; +import com.vectras.qemu.MainActivityCommon; +import com.vectras.qemu.MainSDLActivity; +import com.vectras.qemu.MainService; +import com.vectras.qemu.MainSettingsManager; +import com.vectras.qemu.utils.FileUtils; +import com.vectras.qemu.utils.Machine; +import com.vectras.qemu.utils.QmpClient; +import com.vectras.qemu.utils.RamInfo; +import com.vectras.vm.logger.VectrasStatus; +import com.vectras.vm.utils.UIUtils; + +import java.io.File; +import java.util.ArrayList; +import java.util.Arrays; + +import org.json.JSONException; +import org.json.JSONObject; + +public class StartVM { + + private static final String TAG = "StartVM"; + private static Context context; + + String[] params = null; + + //native lib + private String libqemu = null; + + //qmp server + public int enableqmp; + private String qmp_server; + private int qmp_port; + + //state + public int paused; + public String snapshot_name = null; + public String save_state_name = null; + private String save_dir; + public int current_fd = 0; + + public String base_dir; + public String dns_addr; + public String append = ""; + public boolean busy = false; + public String name; + + //ui + public int enablespice = 0; + public String keyboard_layout = Config.defaultKeyboardLayout; + + public String mouse = null; + public int enablevnc; + public int vnc_allow_external = 0; + public int qmp_allow_external = 0; + public String vnc_passwd = "vectras"; + + // cpu/board settings + private String cpu; + private String arch = "x86"; + private String machine_type; + private int memory = 128; + private int cpuNum = 1; + public int enablekvm; + public int enable_mttcg; + + // disks + public String hda_img_path; + private String hdb_img_path; + private String hdc_img_path; + private String hdd_img_path; + public String shared_folder_path; + public int shared_folder_readonly = 1; + private String hd_cache = "default"; + + //removable devices + public String cd_iso_path; + public String fda_img_path; + public String fdb_img_path; + public String sd_img_path; + + //boot options + private String bootdevice = null; + private String kernel; + private String initrd; + + //graphics + private String vga_type = "std"; + + //audio + public String sound_card; + + // net + private String net_cfg = "None"; + private String nic_card = null; + private String hostfwd = null; + private String guestfwd = null; + + //advanced + private int disableacpi = 0; + private int disablehpet = 0; + private int disabletsc = 0; + public String extra_params; + + /** + * @throws Exception + */ + public StartVM(Context context) throws Exception { + + name = Config.machinename; + base_dir = Config.getBasefileDir(); + save_dir = Config.getMachineDir() + name; + save_state_name = save_dir + "/" + Config.state_filename; + hda_img_path = Config.hda_path; + extra_params = Config.extra_params; + shared_folder_path = Config.sharedFolder; + //extra_params = Config.extra_params; + this.context = context; + this.libqemu = FileUtils.getNativeLibDir(context) + "/libqemu-system-x86_64.so"; + this.arch = "x86_64"; + this.cpuNum = MainSettingsManager.getCpuNum(MainActivityCommon.activity); + if (MainSettingsManager.getMTTCG(MainActivityCommon.activity)) + this.enable_mttcg = 1; + else + this.enable_mttcg = 0; + this.vnc_allow_external = 0; + + } + + public static void onVMResolutionChanged(int width, int height) { + + if (MainSDLActivity.mIsSurfaceReady) + MainSDLActivity.onVMResolutionChanged(width, height); + } + + public void print(String[] params) { + VectrasStatus.logInfo("Params:"); + Log.d(TAG, "Params:"); + for (int i = 0; i < params.length; i++) { + VectrasStatus.logInfo(i + ": " + params[i]); + Log.d(TAG, i + ": " + params[i]); + } + + } + + public String startvm() { + + String res = null; + try { + prepareParams(); + } catch (Exception ex) { + UIUtils.toastLong(context, ex.getMessage()); + return res; + } + + //set the exit code + MainSettingsManager.setExitCode(context, 2); + + try { + res = start(Config.storagedir, this.base_dir, this.libqemu, Config.SDLHintScale, params, this.paused, this.save_state_name); + } catch (Exception ex) { + ex.printStackTrace(); + Log.e(TAG, "Vectras Exception: " + ex.toString()); + } + return res; + } + + public void prepareParams() throws Exception { + + params = null; + ArrayList paramsList = new ArrayList(); + + paramsList.add(libqemu); + + addUIOptions(paramsList); + + addCpuBoardOptions(paramsList); + + addDrives(paramsList); + + addRemovableDrives(paramsList); + + addBootOptions(paramsList); + + addGraphicsOptions(paramsList); + + addAudioOptions(paramsList); + + addNetworkOptions(paramsList); + + addAdvancedOptions(paramsList); + + addGenericOptions(paramsList); + + addStateOptions(paramsList); + + params = (String[]) paramsList.toArray(new String[paramsList.size()]); + + print(params); + + } + + private void addStateOptions(ArrayList paramsList) { + if (paused == 1 && this.save_state_name != null && !save_state_name.equals("")) { + int fd_tmp = FileUtils.get_fd(context, save_state_name); + if (fd_tmp < 0) { + Log.e(TAG, "Error while getting fd for: " + save_state_name); + } else { + //Log.i(TAG, "Got new fd "+fd_tmp + " for: " +save_state_name); + paramsList.add("-incoming"); + paramsList.add("fd:" + fd_tmp); + } + } + } + + private void addUIOptions(ArrayList paramsList) { + if (enablevnc != 0) { + Log.v(TAG, "Enable VNC server"); + paramsList.add("-vnc"); + + if (vnc_allow_external != 0) { + //TODO: Allow connections from External + // Use with x509 auth and TLS for encryption + paramsList.add(":1"); + } else { + // Allow connections only from localhost using localsocket without a password + //paramsList.add(Config.defaultVNCHost+":" + Config.defaultVNCPort); + String qmpParams = "unix:"; + qmpParams += Config.getLocalVNCSocketPath(); + paramsList.add(qmpParams); + } + //Allow monitor console only for VNC, + // SDL for android doesn't support more + // than 1 window + paramsList.add("-monitor"); + paramsList.add("vc"); + + } else if (enablespice != 0) { + //Not working right now + Log.v(TAG, "Enable SPICE server"); + paramsList.add("-spice"); + String spiceParams = "port=5902"; + + if (vnc_allow_external != 0 && vnc_passwd != null) { + spiceParams += ",password="; + spiceParams += vnc_passwd; + } else + spiceParams += ",addr=127.0.0.1"; // Allow only connections from localhost without password + + spiceParams += ",disable-ticketing"; + //argv.add("-chardev"); + //argv.add("spicevm"); + } else { + //SDL needs explicit keyboard layout + Log.v(TAG, "Disabling VNC server, using SDL instead"); + if (keyboard_layout == null) { + paramsList.add("-k"); + paramsList.add("en-us"); + } + + //XXX: monitor, serial, and parallel display crashes cause SDL doesn't support more than 1 window + paramsList.add("-monitor"); + paramsList.add("none"); + + paramsList.add("-serial"); + paramsList.add("none"); + + paramsList.add("-parallel"); + paramsList.add("none"); + } + + if (keyboard_layout != null) { + paramsList.add("-k"); + paramsList.add(keyboard_layout); + } + + if (mouse != null && !mouse.equals("ps2")) { + paramsList.add("-usb"); + paramsList.add("-device"); + paramsList.add(mouse); + } + + } + + private void addAdvancedOptions(ArrayList paramsList) { + + if (disableacpi != 0) { + paramsList.add("-no-acpi"); //disable ACPI + } + if (disablehpet != 0) { + paramsList.add("-no-hpet"); // disable HPET + } + + //TODO:Extra options + if (extra_params != null && !extra_params.trim().equals("")) { + String[] paramsTmp = extra_params.split(" "); + paramsList.addAll(Arrays.asList(paramsTmp)); + } + + } + + private void addAudioOptions(ArrayList paramsList) { + + if (sound_card != null && !sound_card.equals("None")) { + paramsList.add("-soundhw"); + paramsList.add(sound_card); + } + + } + + private void addGenericOptions(ArrayList paramsList) { + + paramsList.add("-L"); + paramsList.add(base_dir); + + //XXX: Snapshots not working currently, use migrate/incoming instead + if (snapshot_name != null && !snapshot_name.equals("")) { + paramsList.add("-loadvm"); + paramsList.add(snapshot_name); + } + + if (enableqmp != 0) { + + paramsList.add("-qmp"); + + if (qmp_allow_external != 0) { + String qmpParams = "tcp:"; + qmpParams += (":" + this.qmp_port); + qmpParams += ",server,nowait"; + paramsList.add(qmpParams); + } else { + //Specify a unix local domain as localhost to limit to local connections only + String qmpParams = "unix:"; + qmpParams += Config.getLocalQMPSocketPath(); + qmpParams += ",server,nowait"; + paramsList.add(qmpParams); + + } + + + } + + //Enable Tracing log + // argv.add("-D"); + // argv.add("/sdcard/vectras/log.txt"); + // argv.add("--trace"); + // argv.add("events=/sdcard/vectras/tmp/events"); + // argv.add("--trace"); + // argv.add("file=/sdcard/vectras/tmp/trace"); + +// paramsList.add("-tb-size"); +// paramsList.add("32M"); //Don't increase it crashes + + paramsList.add("-overcommit"); + paramsList.add("mem-lock=off"); + + paramsList.add("-rtc"); + paramsList.add("base=localtime"); + + paramsList.add("-nodefaults"); + + + //XXX: Usb redir not working under User mode + //Redirect ports (SSH) + // argv.add("-redir"); + // argv.add("5555::22"); + + } + + private void addCpuBoardOptions(ArrayList paramsList) { + + //XXX: SMP is not working correctly for some guest OSes + //so we enable multi core only under KVM + // anyway regular emulation is not gaining any benefit unless mttcg is enabled but that + // doesn't work for x86 guests yet + if (this.cpuNum > 1 && + (enablekvm == 1 || enable_mttcg == 1 || !Config.enableSMPOnlyOnKVM)) { + paramsList.add("-smp"); + paramsList.add(this.cpuNum + ""); + } + + if (machine_type != null && !machine_type.equals("Default")) { + paramsList.add("-M"); + paramsList.add(machine_type); + } + + //FIXME: something is wrong with quoting that doesn't let sparc qemu find the cpu def + // for now we remove the cpu drop downlist items for sparc + if (this.cpu != null && this.cpu.contains(" ")) + cpu = "'" + cpu + "'"; // XXX: needed for sparc cpu names + + //XXX: we disable tsc feature for x86 since some guests are kernel panicking + // if the cpu has not specified by user we use the internal qemu32/64 + if (disabletsc == 1 && (arch.equals("x86") || arch.equals("x86_64"))) { + if (cpu == null || cpu.equals("Default")) { + if (arch.equals("x86")) + cpu = "qemu32"; + else if (arch.equals("x86_64")) + cpu = "qemu64"; + } + cpu += ",-tsc"; + } + + if (this.cpu != null && !cpu.equals("Default")) { + paramsList.add("-cpu"); + paramsList.add(cpu); + + } + + paramsList.add("-m"); + paramsList.add(RamInfo.vectrasMemory() + ""); + + + if (enablekvm != 0) { + paramsList.add("-enable-kvm"); + } else if (this.enable_mttcg != 0 && Machine.isHost64Bit()) { + //XXX: we should only do this for 64bit hosts + paramsList.add("-accel"); + String tcgParams = "tcg"; + if (cpuNum > 1) + tcgParams += ",thread=multi"; + paramsList.add(tcgParams); + //#endif + } + + } + + private void addNetworkOptions(ArrayList paramsList) throws Exception { + + if (this.net_cfg != null) { + paramsList.add("-net"); + if (net_cfg.equals("user")) { + String netParams = net_cfg; + if (hostfwd != null) { + + //hostfwd=[tcp|udp]:[hostaddr]:hostport-[guestaddr]:guestport{,hostfwd=...} + // example forward ssh from guest port 2222 to guest port 22: + // hostfwd=tcp::2222-:22 + if (hostfwd.startsWith("hostfwd")) { + throw new Exception("Invalid format for Host Forward, should be: tcp:hostport1:guestport1,udp:hostport2:questport2,..."); + } + String[] hostfwdparams = hostfwd.split(","); + for (int i = 0; i < hostfwdparams.length; i++) { + netParams += ","; + String[] hostfwdparam = hostfwdparams[i].split(":"); + netParams += ("hostfwd=" + hostfwdparam[0] + "::" + hostfwdparam[1] + "-:" + hostfwdparam[2]); + } + } + if (guestfwd != null) { + netParams += ","; + netParams += guestfwd; + } + paramsList.add(netParams); + } else if (net_cfg.equals("tap")) { + paramsList.add("tap,vlan=0,ifname=tap0,script=no"); + } else if (net_cfg.equals("none")) { + paramsList.add("none"); + } else { + //Unknown interface + paramsList.add("none"); + } + } + + if (nic_card != null) { + paramsList.add("-net"); + String nicParams = "nic"; + if (net_cfg.equals("tap")) + nicParams += ",vlan=0"; + if (!nic_card.equals("Default")) + nicParams += (",model=" + nic_card); + paramsList.add(nicParams); + } + } + + private void addGraphicsOptions(ArrayList paramsList) { + if (vga_type != null) { + if (vga_type.equals("Default")) { + //do nothing + } else if (vga_type.equals("virtio-gpu-pci")) { + paramsList.add("-device"); + paramsList.add(vga_type); + } else if (vga_type.equals("nographic")) { + paramsList.add("-nographic"); + } else { + paramsList.add("-vga"); + paramsList.add(vga_type); + } + } + + + } + + private void addBootOptions(ArrayList paramsList) { + if (this.bootdevice != null) { + paramsList.add("-boot"); + paramsList.add(bootdevice); + } + + if (this.kernel != null && !this.kernel.equals("")) { + paramsList.add("-kernel"); + paramsList.add(this.kernel); + } + + if (initrd != null && !initrd.equals("")) { + paramsList.add("-initrd"); + paramsList.add(initrd); + } + + if (append != null && !append.equals("")) { + paramsList.add("-append"); + paramsList.add(append); + } + } + + public void addDrives(ArrayList paramsList) { + if (hda_img_path != null) { + paramsList.add("-drive"); //empty + String param = "index=0"; + if (Config.enable_hd_if) { + param += ",if="; + param += Config.hd_if_type; + } + param += ",media=disk"; + if (!hda_img_path.equals("")) { + param += ",file=" + hda_img_path; + } + paramsList.add(param); + } + + if (hdb_img_path != null) { + paramsList.add("-drive"); //empty + String param = "index=1"; + if (Config.enable_hd_if) { + param += ",if="; + param += Config.hd_if_type; + } + param += ",media=disk"; + if (!hdb_img_path.equals("")) { + param += ",file=" + hdb_img_path; + } + paramsList.add(param); + } + + if (hdc_img_path != null) { + paramsList.add("-drive"); //empty + String param = "index=2"; + if (Config.enable_hd_if) { + param += ",if="; + param += Config.hd_if_type; + } + param += ",media=disk"; + if (!hdc_img_path.equals("")) { + param += ",file=" + hdc_img_path; + } + paramsList.add(param); + } + + if (hdd_img_path != null) { + paramsList.add("-drive"); //empty + String param = "index=3"; + if (Config.enable_hd_if) { + param += ",if="; + param += Config.hd_if_type; + } + param += ",media=disk"; + if (!hdd_img_path.equals("")) { + param += ",file=" + hdd_img_path; + } + paramsList.add(param); + } else if (shared_folder_path != null) { + //XXX; We use hdd to mount any virtual fat drives + paramsList.add("-drive"); //empty + String driveParams = "index=3"; + driveParams += ",media=disk"; + if (Config.enable_hd_if) { + driveParams += ",if="; + driveParams += Config.hd_if_type; + } + driveParams += ",format=raw"; + driveParams += ",file=fat:"; + driveParams += "rw:"; //Always Read/Write + driveParams += shared_folder_path; + paramsList.add(driveParams); + } + + } + + public void addRemovableDrives(ArrayList paramsList) { + + if (cd_iso_path != null) { + paramsList.add("-drive"); //empty + String param = "index=2"; + if (Config.enable_hd_if) { + param += ",if="; + param += Config.hd_if_type; + } + param += ",media=cdrom"; + if (!cd_iso_path.equals("")) { + param += ",file=" + cd_iso_path; + } + paramsList.add(param); + } + + if (Config.enableEmulatedFloppy && fda_img_path != null) { + paramsList.add("-drive"); //empty + String param = "index=0,if=floppy"; + if (!fda_img_path.equals("")) { + param += ",file=" + fda_img_path; + } + paramsList.add(param); + } + + if (Config.enableEmulatedFloppy && fdb_img_path != null) { + paramsList.add("-drive"); //empty + String param = "index=1,if=floppy"; + if (!fdb_img_path.equals("")) { + param += ",file=" + fdb_img_path; + } + paramsList.add(param); + } + + if (Config.enableEmulatedSDCard && sd_img_path != null) { + paramsList.add("-device"); + paramsList.add("sd-card,drive=sd0,bus=sd-bus"); + paramsList.add("-drive"); + String param = "if=none,id=sd0"; + if (!sd_img_path.equals("")) { + param += ",file=" + sd_img_path; + } + paramsList.add(param); + } + + } + + //JNI Methods + public native String start(String storage_dir, String base_dir, String lib_path, int sdl_scale_hint, Object[] params, int paused, String save_state_name); + + public native String stop(int restart); + + public native void setsdlrefreshrate(int value); + + public native void setvncrefreshrate(int value); + + public native int getsdlrefreshrate(); + + public native int getvncrefreshrate(); + + private native int onmouse(int button, int action, int relative, float x, float y); + + private native int setrelativemousemode(int relativemousemode); + + protected void vncchangepassword(String vnc_passwd) { + String res = QmpClient.sendCommand(QmpClient.changevncpasswd(vnc_passwd)); + String desc = null; + if (res != null && !res.equals("")) { + try { + JSONObject resObj = new JSONObject(res); + if (resObj != null && !resObj.equals("") && res.contains("error")) { + String resInfo = resObj.getString("error"); + if (resInfo != null && !resInfo.equals("")) { + JSONObject resInfoObj = new JSONObject(resInfo); + desc = resInfoObj.getString("desc"); + UIUtils.toastLong(context, "Could not set VNC Password: " + desc); + Log.e(TAG, desc); + } + } + + } catch (JSONException e) { + e.printStackTrace(); + } + } + } + + protected String changedev(String dev, String dev_value) { + QmpClient.sendCommand(QmpClient.changedev(dev, dev_value)); + String display_dev_value = FileUtils.getFullPathFromDocumentFilePath(dev_value); + return "Changed device: " + dev + " to " + display_dev_value; + } + + protected String ejectdev(String dev) { + QmpClient.sendCommand(QmpClient.ejectdev(dev)); + return "Ejected device: " + dev; + } + + public String startvm(Context context, int ui) { + MainService.executor = this; + Intent i = new Intent(Config.ACTION_START, null, context, MainService.class); + Bundle b = new Bundle(); + // b.putString("machine_type", this.machine_type); + b.putInt("ui", ui); + i.putExtras(b); + context.startService(i); + Log.v(TAG, "start VM service"); + return "startVMService"; + + } + + public void stopvm(final int restart) { + + new Thread(new Runnable() { + @Override + public void run() { + doStopVM(restart); + } + }).start(); + } + + public void doStopVM(final int restart) { + + if (restart == 0) { + MainService.stopService(); + + //XXX: Wait till service goes down + try { + Thread.sleep(2000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + if (restart != 0) { + QmpClient.sendCommand(QmpClient.reset()); + } else { + //XXX: Qmp command only halts the VM but doesn't exit + // so we use force close +// QmpClient.sendCommand(QmpClient.powerDown()); + stop(restart); + } + + } + + public String savevm(String statename) { + // Set to delete previous snapshots after vm resumed + Log.v(TAG, "Save Snapshot"); + this.snapshot_name = statename; + + String res = null; + //TODO: + //res = QmpClient.sendCommand(QmpClient.saveSnapshot()); + return res; + } + + public String resumevm() { + // Set to delete previous snapshots after vm resumed + Log.v(TAG, "Resume the VM"); + String res = startvm(); + Log.d(TAG, res); + return res; + } + + public void change_vnc_password() { + Thread thread = new Thread(new Runnable() { + public void run() { + vncchangepassword(vnc_passwd); + } + }); + thread.start(); + } + + public String get_state() { + + return null; + } + + public void change_dev(final String dev, final String image_path) { + + Thread thread = new Thread(new Runnable() { + public void run() { + String image_path_conv = FileUtils.convertDocumentFilePath(image_path); + if (image_path_conv == null || image_path_conv.trim().equals("")) { + StartVM.this.busy = true; + String res = StartVM.this.ejectdev(dev); + Log.d(TAG, res); + StartVM.this.busy = false; + } else if (FileUtils.fileValid(context, image_path_conv)) { + StartVM.this.busy = true; + String res = StartVM.this.changedev(dev, image_path_conv); + Log.d(TAG, res); + StartVM.this.busy = false; + } else { + Log.d(TAG, "File does not exist"); + } + } + }); + thread.setPriority(Thread.MIN_PRIORITY); + thread.start(); + + + } + + public int get_fd(String path) { + int fd = FileUtils.get_fd(context, path); + return fd; + + } + + public int close_fd(int fd) { + int res = FileUtils.close_fd(fd); + return res; + + } + + public void prepPaths() { + File destDir = new File(save_dir); + if (!destDir.exists()) { + destDir.mkdirs(); + } + + // Protect the paths from qemu thinking they contain a protocol in the string + + this.hda_img_path = FileUtils.convertDocumentFilePath(this.hda_img_path); + if (this.hda_img_path != null && hda_img_path.equals("")) { + hda_img_path = null; + } + this.hdb_img_path = FileUtils.convertDocumentFilePath(this.hdb_img_path); + if (this.hdb_img_path != null && hdb_img_path.equals("")) { + hdb_img_path = null; + } + this.hdc_img_path = FileUtils.convertDocumentFilePath(this.hdc_img_path); + if (this.hdc_img_path != null && hdc_img_path.equals("")) { + hdc_img_path = null; + } + this.hdd_img_path = FileUtils.convertDocumentFilePath(this.hdd_img_path); + if (this.hdd_img_path != null && hdd_img_path.equals("")) { + hdd_img_path = null; + } + + // Removable disks + this.cd_iso_path = FileUtils.convertDocumentFilePath(this.cd_iso_path); + this.fda_img_path = FileUtils.convertDocumentFilePath(this.fda_img_path); + + this.fdb_img_path = FileUtils.convertDocumentFilePath(this.fdb_img_path); + this.sd_img_path = FileUtils.convertDocumentFilePath(this.sd_img_path); + + this.kernel = FileUtils.convertDocumentFilePath(this.kernel); + this.initrd = FileUtils.convertDocumentFilePath(this.initrd); + } + + public int setRelativeMouseMode(int relative) { + return setrelativemousemode(relative); + } + + public int onVectrasMouse(int button, int action, int relative, float x, float y) { + //XXX: Make sure that mouse motion is not triggering crashes in SDL while resizing + if (!MainSDLActivity.mIsSurfaceReady || MainSDLActivity.isResizing) { +// Log.w(TAG, "onVectrasMouse: Ignoring mouse event surface not ready"); + return -1; + } + + //XXX: Check boundaries, perhaps not necessary since SDL is also doing the same thing + if (relative == 1 + || (x >= 0 && x <= MainSDLActivity.vm_width && y >= 0 && y <= MainSDLActivity.vm_height) + || (action == MotionEvent.ACTION_SCROLL)) { +// Log.d(TAG, "onVectrasMouse: B: " + button + ", A: " + action + ", R: " + relative + ", X: " + x + ", Y: " + y); + return onmouse(button, action, relative, x, y); + } + return -1; + } +} + diff --git a/app/src/main/java/com/vectras/qemu/utils/FileInstaller.java b/app/src/main/java/com/vectras/qemu/utils/FileInstaller.java new file mode 100644 index 0000000..fbb2a0d --- /dev/null +++ b/app/src/main/java/com/vectras/qemu/utils/FileInstaller.java @@ -0,0 +1,271 @@ +/* + Copyright (C) Max Kastanas 2012 + + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package com.vectras.qemu.utils; + +import android.app.Activity; +import android.content.res.AssetManager; +import android.net.Uri; +import androidx.documentfile.provider.DocumentFile; +import android.util.Log; + +import com.vectras.qemu.Config; +import com.vectras.vm.utils.UIUtils; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * + * @author dev + */ +public class FileInstaller { + + public static void installFiles(Activity activity, boolean force) { + + Log.v("Installer", "Installing files..."); + File tmpDir = new File(Config.getBasefileDir()); + if (!tmpDir.exists()) { + tmpDir.mkdirs(); + } + + File tmpDir1 = new File(Config.getMachineDir()); + if (!tmpDir1.exists()) { + tmpDir1.mkdirs(); + } + + + //Install base dir + File dir = new File(Config.getBasefileDir()); + if (dir.exists() && dir.isDirectory()) { + //don't create again + } else if (dir.exists() && !dir.isDirectory()) { + Log.v("Installer", "Could not create Dir, file found: " + Config.getBasefileDir()); + return; + } else if (!dir.exists()) { + dir.mkdir(); + } + + String destDir = Config.getBasefileDir(); + + //Get each file in assets under ./roms/ and install in SDCARD + AssetManager am = activity.getResources().getAssets(); + String[] files = null; + try { + files = am.list("roms"); + } catch (IOException ex) { + Logger.getLogger(FileInstaller.class.getName()).log(Level.SEVERE, null, ex); + Log.v("Installer", "Could not install files: " + ex.getMessage()); + return; + } + + for (int i = 0; i < files.length; i++) { + //Log.v("Installer", "File: " + files[i]); + String[] subfiles = null; + try { + subfiles = am.list("roms/" + files[i]); + } catch (IOException ex) { + Logger.getLogger(FileInstaller.class.getName()).log(Level.SEVERE, null, ex); + } + if (subfiles != null && subfiles.length > 0) { + //Install base dir + File dir1 = new File(Config.getBasefileDir() + files[i]); + if (dir1.exists() && dir1.isDirectory()) { + //don't create again + } else if (dir1.exists() && !dir1.isDirectory()) { + Log.v("Installer", "Could not create Dir, file found: " + Config.getBasefileDir() + files[i]); + return; + } else if (!dir1.exists()) { + dir1.mkdir(); + } + for (int k = 0; k < subfiles.length; k++) { + + File file = new File(destDir, files[i] + "/" + subfiles[k]); + if(!file.exists() || force) { + Log.v("Installer", "Installing file: " + file.getPath()); + installAssetFile(activity, files[i] + "/" + subfiles[k], destDir, "roms", null); + } + } + } else { + File file = new File(destDir, files[i]); + if(!file.exists() || force) { + Log.v("Installer", "Installing file: " + file.getPath()); + installAssetFile(activity, files[i], Config.getBasefileDir(), "roms", null); + } + } + } +// InputStream is = am.open(srcFile); + + } + + public static boolean installAssetFile(Activity activity, String srcFile, + String destDir, String assetsDir, String destFile) { + try { + AssetManager am = activity.getResources().getAssets(); // get the local asset manager + InputStream is = am.open(assetsDir + "/" + srcFile); // open the input stream for reading + File destDirF = new File(destDir); + if (!destDirF.exists()) { + boolean res = destDirF.mkdirs(); + if(!res){ + UIUtils.toastShort(activity, "Could not create directory for image"); + } + } + + if(destFile==null) + destFile=srcFile; + OutputStream os = new FileOutputStream(destDir + "/" + destFile); + byte[] buf = new byte[8092]; + int n; + while ((n = is.read(buf)) > 0) { + os.write(buf, 0, n); + } + os.close(); + is.close(); + return true; + } catch (Exception ex) { + Log.e("Installer", "failed to install file: " + destFile + ", Error:" + ex.getMessage()); + return false; + } + } + + public static Uri installImageTemplateToSDCard(Activity activity, String srcFile, + Uri destDir, String assetsDir, String destFile) { + + DocumentFile destFileF = null; + OutputStream os = null; + InputStream is = null; + Uri uri = null; + + try { + + DocumentFile dir = DocumentFile.fromTreeUri(activity, destDir); + AssetManager am = activity.getResources().getAssets(); // get the local asset manager + is = am.open(assetsDir + "/" + srcFile); // open the input stream for reading + + if(destFile==null) + destFile=srcFile; + + //Create the file if doesn't exist + destFileF = dir.findFile(destFile); + if(destFileF == null) { + destFileF = dir.createFile("application/octet-stream", destFile); + } + else { + UIUtils.toastShort(activity, "File exists, choose another filename"); + return null; + } + + //Write to the dest + os = activity.getContentResolver().openOutputStream(destFileF.getUri()); + //OutputStream os = new FileOutputStream(destDir + "/" + destFile); + byte[] buf = new byte[8092]; + int n; + while ((n = is.read(buf)) > 0) { + os.write(buf, 0, n); + } + + //success + uri = destFileF.getUri(); + + } catch (Exception ex) { + Log.e("Installer", "failed to install file: " + destFile + ", Error:" + ex.getMessage()); + } finally { + if(os!=null) { + try { + os.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + if(is!=null) { + try { + is.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + } + return uri; + } + + + public static String installImageTemplateToExternalStorage(Activity activity, String srcFile, + String destDir, String assetsDir, String destFile) { + + File file = new File(destDir, destFile); + String filePath = null; + OutputStream os = null; + InputStream is = null; + try { + + AssetManager am = activity.getResources().getAssets(); // get the local asset manager + is = am.open(assetsDir + "/" + srcFile); // open the input stream for reading + + if(destFile==null) + destFile=srcFile; + + //Create the file if doesn't exist + if(!file.exists()){ + file.createNewFile(); + } + else { + UIUtils.toastShort(activity, "File exists, choose another filename"); + return null; + } + + //Write to the dest + os = new FileOutputStream(file); + + //OutputStream os = new FileOutputStream(destDir + "/" + destFile); + byte[] buf = new byte[8092]; + int n; + while ((n = is.read(buf)) > 0) { + os.write(buf, 0, n); + } + + //success + filePath = file.getAbsolutePath(); + + } catch (Exception ex) { + Log.e("Installer", "failed to install file: " + destFile + ", Error:" + ex.getMessage()); + } finally { + if(os!=null) { + try { + os.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + if(is!=null) { + try { + is.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + } + return filePath; + } +} diff --git a/app/src/main/java/com/vectras/qemu/utils/FileUtils.java b/app/src/main/java/com/vectras/qemu/utils/FileUtils.java new file mode 100644 index 0000000..ccf86d4 --- /dev/null +++ b/app/src/main/java/com/vectras/qemu/utils/FileUtils.java @@ -0,0 +1,647 @@ +/* +Copyright (C) Max Kastanas 2012 + + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package com.vectras.qemu.utils; + +import java.io.BufferedReader; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.io.UnsupportedEncodingException; +import java.net.URLDecoder; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Hashtable; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; + +import android.app.Activity; +import android.content.Context; +import android.content.Intent; +import android.net.Uri; +import android.os.Bundle; +import android.os.ParcelFileDescriptor; +import androidx.documentfile.provider.DocumentFile; +import android.text.Spannable; +import android.util.Log; +import android.webkit.MimeTypeMap; + +import com.vectras.vm.R; +import com.vectras.qemu.Config; +import com.vectras.vm.utils.UIUtils; + +/** + * @author dev + */ +public class FileUtils { + private final static String TAG = "FileUtils"; + public static HashMap fds = new HashMap(); + + public static String getNativeLibDir(Context context) { + return context.getApplicationInfo().nativeLibraryDir; + } + + public static String getFullPathFromDocumentFilePath(String filePath) { + + filePath = filePath.replaceAll("%3A", "^3A"); + int index = filePath.lastIndexOf("^3A"); + if (index > 0) + filePath = filePath.substring(index + 3); + if (!filePath.startsWith("/")) + filePath = "/" + filePath; + +// filePath = filePath.replaceAll("%2F", "/"); +// filePath = filePath.replaceAll("\\^2F", "/"); + + //remove any spaces encoded by the ASF + try { + filePath = URLDecoder.decode(filePath, "UTF-8"); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + + return filePath; + } + + public static String getFilenameFromPath(String filePath) { + filePath = filePath.replaceAll("%2F", "/"); + filePath = filePath.replaceAll("%3A", "/"); + filePath = filePath.replaceAll("\\^2F", "/"); + filePath = filePath.replaceAll("\\^3A", "/"); + + + int index = filePath.lastIndexOf("/"); + if (index > 0) + return filePath.substring(index + 1); + return filePath; + } + + public static String unconvertDocumentFilePath(String filePath) { + if (filePath != null && filePath.startsWith("/content//")) { + filePath = filePath.replace("/content//", "content://"); + filePath = filePath.replaceAll("\\^\\^\\^", "%"); + } + return filePath; + } + + public static String convertDocumentFilePath(String filePath) { + if (filePath != null && filePath.startsWith("content://")) { + filePath = filePath.replace("content://", "/content//"); + filePath = filePath.replaceAll("%", "\\^\\^\\^");; + + } + return filePath; + } + + public static void saveFileContents(String filePath, String contents) { + // TODO: we assume that the contents are of small size so we keep in an array + byteArrayToFile(contents.getBytes(), new File(filePath)); + } + + public static void byteArrayToFile(byte[] byteData, File filePath) { + + try { + FileOutputStream fos = new FileOutputStream(filePath); + fos.write(byteData); + fos.close(); + + } catch (FileNotFoundException ex) { + System.out.println("FileNotFoundException : " + ex); + } catch (IOException ioe) { + System.out.println("IOException : " + ioe); + } + + } + public static InputStream getStreamFromFilePath(Context context, String importFilePath) throws FileNotFoundException { + InputStream stream = null; + if (importFilePath.startsWith("content://")) { + Uri uri = Uri.parse(importFilePath); + String mode = "rw"; + ParcelFileDescriptor pfd = context.getContentResolver().openFileDescriptor(uri, mode); + return new FileInputStream(pfd.getFileDescriptor()); + } else { + return new FileInputStream(importFilePath); + } + } + + public static String getFileContents(String filePath) { + + File file = new File(filePath); + if(!file.exists()) + return ""; + StringBuilder builder = new StringBuilder(""); + try { + FileInputStream stream = new FileInputStream(file); + byte[] buff = new byte[32768]; + int bytesRead = 0; + while ((bytesRead = stream.read(buff, 0, buff.length)) > 0) { + builder.append(new String(buff, "UTF-8")); + } + } catch (Exception e) { + e.printStackTrace(); + } + + String contents = builder.toString(); + return contents; + } + + public static void viewVectrasLog(final Activity activity) { + + String contents = FileUtils.getFileContents(Config.logFilePath); + + if (contents.length() > 50 * 1024) + contents = contents.substring(0, 25 * 1024) + + "\n.....\n" + + contents.substring(contents.length() - 25 * 1024); + + final String finalContents = contents; + final Spannable contentsFormatted = UIUtils.formatAndroidLog(contents); + + activity.runOnUiThread(new Runnable() { + @Override + public void run() { + + if (Config.viewLogInternally) { + UIUtils.UIAlertLog(activity, "Vectras Log", contentsFormatted); + } else { + try { + Intent intent = new Intent(Intent.ACTION_EDIT); + File file = new File(Config.logFilePath); + Uri uri = Uri.fromFile(file); + intent.setDataAndType(uri, "text/plain"); + activity.startActivity(intent); + } catch (Exception ex) { +// UIUtils.toastShort(activity, "Could not find a Text Viewer on your device"); + UIUtils.UIAlertLog(activity, "Vectras Log", contentsFormatted); + } + } + + + } + }); + + } + + public static boolean fileValid(Context context, String path) { + + if (path == null || path.equals("")) + return true; + if (path.startsWith("content://") || path.startsWith("/content/")) { + int fd = get_fd(context, path); + if (fd <= 0) + return false; + } else { + File file = new File(path); + return file.exists(); + } + return true; + } + + //TODO: we should pass the modes from the backend and translate them + // instead of blindly using "rw". ie ISOs should be read only. + public static int get_fd(final Context context, String path) { + synchronized (fds) { + int fd = 0; + if (path == null) + return 0; + +// Log.d(TAG, "Opening Filepath: " + path); + if (path.startsWith("/content//") || path.startsWith("content://")) { + String npath = unconvertDocumentFilePath(path); + +//Is this needed? +// FileInfo info = getExistingFd(npath); +// if (info!=null) { +// ParcelFileDescriptor pfd = info.pfd; +// fd = pfd.getFd(); +// Log.d(TAG, "Retrieved hashed documentfile: " + npath + ", FD: " + fd); +// return fd; +// } + + +// Log.d(TAG, "Opening unconverted: " + npath); + try { + Uri uri = Uri.parse(npath); + String mode = "rw"; + if (path.toLowerCase().endsWith(".iso")) + mode = "r"; + ParcelFileDescriptor pfd = context.getContentResolver().openFileDescriptor(uri, mode); + fd = pfd.getFd(); +// Log.d(TAG, "Opening DocumentFile: " + npath + ", FD: " + fd); + fds.put(fd, new FileInfo(path, npath, pfd)); + + } catch (Exception e) { + Log.e(TAG, "Could not open DocumentFile: " + npath + ", FD: " + fd); + if(Config.debug) + e.printStackTrace(); + } + } else { + //Is this needed? +// FileInfo info = getExistingFd(path); +// if (info!=null) { +// ParcelFileDescriptor pfd = info.pfd; +// fd = pfd.getFd(); +// Log.d(TAG, "Retrieved hashed file: " + path + ", FD: " + fd); +// return fd; +// } + + try { + int mode = ParcelFileDescriptor.MODE_READ_WRITE; + if (path.toLowerCase().endsWith(".iso")) + mode = ParcelFileDescriptor.MODE_READ_ONLY; + + File file = new File(path); + if (!file.exists()) + file.createNewFile(); + ParcelFileDescriptor pfd = ParcelFileDescriptor.open(file, mode); + fd = pfd.getFd(); + fds.put(fd, new FileInfo(path, path, pfd)); + Log.d(TAG, "Opening File: " + path + ", FD: " + fd); + } catch (Exception e) { + Log.e(TAG, "Could not open File: " + path + ", FD: " + fd); + if(Config.debug) + e.printStackTrace(); + } + + } + return fd; + } + } + + private static FileInfo getExistingFd(String npath) { + Set> fileInfoSet = fds.entrySet(); + Iterator> iter = fileInfoSet.iterator(); + while (iter.hasNext()) { + Map.Entry entry = iter.next(); + FileInfo fileInfo = entry.getValue(); + if (fileInfo.npath.equals(npath)) { + return fileInfo; + } + } + return null; + } + + public static void close_fds() { + synchronized (fds) { + Integer[] fds = FileUtils.fds.keySet().toArray(new Integer[FileUtils.fds.keySet().size()]); + for (int i = 0; i < fds.length; i++) { + FileUtils.close_fd(fds[i]); + } + } + } + + public static int close_fd(int fd) { + if(!Config.closeFileDescriptors) { + return 0; + } + synchronized (fds) { +// Log.d(TAG, "Closing FD: " + fd); + if (FileUtils.fds.containsKey(fd)) { + + FileInfo info = FileUtils.fds.get(fd); + + + try { + + ParcelFileDescriptor pfd = info.pfd; + try { + pfd.getFileDescriptor().sync(); + } catch (IOException e) { + if(Config.debug) { + Log.w(TAG, "Syncing DocumentFile: " + info.path + ": " + fd + " : " + e); + e.printStackTrace(); + } + } + +// Log.d(TAG, "Closing DocumentFile: " + info.npath + ", FD: " + fd); + pfd.close(); + FileUtils.fds.remove(fd); + return 0; // success for Native side + } catch (IOException e) { + Log.e(TAG, "Error Closing DocumentFile: " + info.path + ": " + fd + " : " + e); + if(Config.debug) + e.printStackTrace(); + } + + + } else { + + ParcelFileDescriptor pfd = null; + String path = "unknown"; + try { + + //xxx: check the hash + FileInfo info = FileUtils.fds.get(fd); + if(info!=null) { + pfd = info.pfd; + path = info.path; +// Log.d(TAG, "Closing hashe File FD: " + fd + ": " + info.path); + } + + //xxx: else get a new parcel + if(pfd == null) + pfd = ParcelFileDescriptor.fromFd(fd); + +// Log.d(TAG, "Closing File FD: " + fd); + try { + pfd.getFileDescriptor().sync(); + } catch (IOException e) { + if(Config.debug) { + Log.e(TAG, "Error Syncing File: " + path + ": " + fd + " : " + e); + e.printStackTrace(); + } + } + + pfd.close(); + return 0; + } catch (Exception e) { + Log.e(TAG, "Error Closing File FD: " + path + ": " + fd + " : " + e); + if(Config.debug) + e.printStackTrace(); + } + } + return -1; + } + } + + public static void startLogging() { + + if (Config.logFilePath == null) { + Log.e(TAG, "Log file is not setup"); + return; + } + + Thread t = new Thread(new Runnable() { + public void run() { + + FileOutputStream os = null; + File logFile = null; + try { + logFile = new File(Config.logFilePath); + if (logFile.exists()) { + logFile.delete(); + } + logFile.createNewFile(); + Runtime.getRuntime().exec("logcat -c"); + Process process = Runtime.getRuntime().exec("logcat v main"); + os = new FileOutputStream(logFile); + BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream())); + + StringBuilder log = new StringBuilder(""); + String line = ""; + while ((line = bufferedReader.readLine()) != null) { + log.setLength(0); + log.append(line).append("\n"); + os.write(log.toString().getBytes("UTF-8")); + os.flush(); + } + } catch (IOException e) { + e.printStackTrace(); + } finally { + try { + if (os != null) { + os.flush(); + os.close(); + } + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + } + + } + }); + t.setName("VectrasLogger"); + t.start(); + } + + public static String LoadFile(Activity activity, String fileName, boolean loadFromRawFolder) throws IOException { + // Create a InputStream to read the file into + InputStream iS; + if (loadFromRawFolder) { + // get the resource id from the file name + int rID = activity.getResources().getIdentifier(activity.getClass().getPackage().getName() + ":raw/" + fileName, + null, null); + // get the file as a stream + iS = activity.getResources().openRawResource(rID); + } else { + // get the file as a stream + iS = activity.getResources().getAssets().open(fileName); + } + + ByteArrayOutputStream oS = new ByteArrayOutputStream(); + byte[] buffer = new byte[iS.available()]; + int bytesRead = 0; + while ((bytesRead = iS.read(buffer)) > 0) { + oS.write(buffer); + } + oS.close(); + iS.close(); + + // return the output stream as a String + return oS.toString(); + } + + public static String getExtensionFromFilename(String fileName) { + if (fileName == null) + return ""; + + int index = fileName.lastIndexOf("."); + if (index >= 0) { + return fileName.substring(index + 1); + } else + return ""; + } + + public static int getIconForFile(String file) { +// file = file.toLowerCase(); +// String ext = FileUtils.getExtensionFromFilename(file).toLowerCase(); +// +// if(ext.equals("img") || ext.equals("qcow") +// || ext.equals("qcow2") || ext.equals("vmdk") || ext.equals("vdi") || ext.equals("cow") +// || ext.equals("dmg") || ext.equals("bochs") || ext.equals("vpc") +// || ext.equals("vhd") || ext.equals("fs")) +// return R.drawable.harddisk; +// else if(ext.equals("iso")) +// return R.drawable.cd; +// else if(ext.equals("ima")) +// return R.drawable.floppy; +// else if(ext.equals("csv")) +// return R.drawable.importvms; +// else if(file.contains("kernel") || file.contains("vmlinuz") || file.contains("initrd")) +// return R.drawable.sysfile; +// else +// return R.drawable.close; + return R.mipmap.ic_launcher; +// + } + + + + + public static Uri saveLogFileSDCard(Activity activity, + Uri destDir) { + + DocumentFile destFileF = null; + OutputStream os = null; + Uri uri = null; + + try { + String logFileContents = getFileContents(Config.logFilePath); + DocumentFile dir = DocumentFile.fromTreeUri(activity, destDir); + + //Create the file if doesn't exist + destFileF = dir.findFile(Config.destLogFilename); + if(destFileF == null) { + destFileF = dir.createFile(MimeTypeMap.getSingleton().getMimeTypeFromExtension("txt"), Config.destLogFilename); + } + + //Write to the dest + os = activity.getContentResolver().openOutputStream(destFileF.getUri()); + os.write(logFileContents.getBytes()); + + //success + uri = destFileF.getUri(); + + } catch (Exception ex) { + UIUtils.toastShort(activity, "Failed to save log file: " + ex.getMessage()); + } finally { + if(os!=null) { + try { + os.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + } + return uri; + } + + public static String saveLogFileLegacy(Activity activity, + String destLogFilePath) { + + String filePath = null; + File destFileF = new File(destLogFilePath, Config.destLogFilename); + + try { + String logFileContents = getFileContents(Config.logFilePath); + FileUtils.saveFileContents(destFileF.getAbsolutePath(), logFileContents); + + //success + filePath = destFileF.getAbsolutePath(); + + } catch (Exception ex) { + UIUtils.toastShort(activity, "Failed to save log file: " + destFileF.getAbsolutePath() + ", Error:" + ex.getMessage()); + } finally { + } + return filePath; + } + + + public static String getFileUriFromIntent(Activity activity, Intent data, boolean write) { + if(data == null) + return null; + + Uri uri = data.getData(); + DocumentFile pickedFile = DocumentFile.fromSingleUri(activity, uri); + String file = uri.toString(); + if (!file.contains("com.android.externalstorage.documents")) { + UIUtils.showFileNotSupported(activity); + return null; + } + activity.grantUriPermission(activity.getPackageName(), uri, Intent.FLAG_GRANT_READ_URI_PERMISSION); + if(write) + activity.grantUriPermission(activity.getPackageName(), uri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION); + activity.grantUriPermission(activity.getPackageName(), uri, Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); + + int takeFlags = data.getFlags() & Intent.FLAG_GRANT_READ_URI_PERMISSION; + if(write) + takeFlags = takeFlags | Intent.FLAG_GRANT_WRITE_URI_PERMISSION; + + activity.getContentResolver().takePersistableUriPermission(uri, takeFlags); + return file; + } + + public static String getDirPathFromIntent(Activity activity, Intent data) { + if(data == null) + return null; + Bundle b = data.getExtras(); + String file = b.getString("currDir"); + return file; + } + + + public static String getFilePathFromIntent(Activity activity, Intent data) { + if(data == null) + return null; + Bundle b = data.getExtras(); + String file = b.getString("file"); + return file; + } + + public static class FileInfo { + public String path; + public String npath; + public ParcelFileDescriptor pfd; + + public FileInfo(String path, String npath, ParcelFileDescriptor pfd) { + this.npath = npath; + this.path = path; + this.pfd = pfd; + } + } + + + + public static void saveLogToFile(final Activity activity, final String logFileDestDir) { + + + Thread t = new Thread(new Runnable() { + public void run() { + + String displayName = null; + if (logFileDestDir.startsWith("content://")) { + Uri exportDirUri = Uri.parse(logFileDestDir); + Uri fileCreatedUri = FileUtils.saveLogFileSDCard(activity, + exportDirUri); + displayName = FileUtils.getFullPathFromDocumentFilePath(fileCreatedUri.toString()); + } else { + String filePath = FileUtils.saveLogFileLegacy(activity, logFileDestDir); + displayName = filePath; + } + + if(displayName!=null){ + + UIUtils.toastShort(activity, "Logfile saved"); + } + } + }); + t.start(); + } + + +} diff --git a/app/src/main/java/com/vectras/qemu/utils/Machine.java b/app/src/main/java/com/vectras/qemu/utils/Machine.java new file mode 100644 index 0000000..b9079d3 --- /dev/null +++ b/app/src/main/java/com/vectras/qemu/utils/Machine.java @@ -0,0 +1,222 @@ +package com.vectras.qemu.utils; + +import android.app.Activity; +import android.app.AlertDialog; +import android.content.Context; +import android.content.DialogInterface; +import android.os.Build; +import android.os.Handler; +import android.os.Looper; +import android.util.Log; +import com.vectras.qemu.Config; +import com.vectras.qemu.MainActivityCommon; +import com.vectras.vm.R; +import com.vectras.vm.utils.UIUtils; + +import org.json.JSONException; +import org.json.JSONObject; + +public class Machine { + + public static final String EMPTY = "empty"; + public static String TAG = "Machine"; + + public static void promptPausedVM(final Activity activity) { + + new AlertDialog.Builder(activity, R.style.MainDialogTheme).setCancelable(false).setTitle("Paused").setMessage("VM is now Paused tap OK to exit") + .setPositiveButton("OK", new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int which) { + + Log.i(TAG, "VM Paused, Shutting Down"); + if (activity.getParent() != null) { + activity.getParent().finish(); + } else { + activity.finish(); + } + + if (MainActivityCommon.vmexecutor != null) { + MainActivityCommon.vmexecutor.stopvm(0); + } + } + }).show(); + } + + + public static void onRestartVM(final Context context) { + Thread t = new Thread(new Runnable() { + public void run() { + if (MainActivityCommon.vmexecutor != null) { + Log.v(TAG, "Restarting the VM..."); + MainActivityCommon.vmexecutor.stopvm(1); + + MainActivityCommon.vmStarted = true; + if(Config.showToast) + UIUtils.toastShort(context, "VM Reset"); + + } else { + if(Config.showToast) + UIUtils.toastShort(context, "VM Not Running"); + } + } + }); + t.start(); + } + + public static void pausedErrorVM(Activity activity, String errStr) { + + errStr = errStr != null ? errStr : "Could not pause VM. View log for details"; + + new AlertDialog.Builder(activity, R.style.MainDialogTheme).setTitle("Error").setMessage(errStr) + .setPositiveButton("OK", new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int which) { + + Thread t = new Thread(new Runnable() { + public void run() { + String command = QmpClient.cont(); + String msg = QmpClient.sendCommand(command); + } + }); + t.start(); + } + }).show(); + } + + public static void stopVM(final Activity activity) { + + new AlertDialog.Builder(activity, R.style.MainDialogTheme).setTitle("Shutdown VM") + .setMessage("To avoid any corrupt data make sure you " + + "have already shutdown the Operating system from within the VM. Continue?") + .setPositiveButton("Yes", new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int which) { + if (activity.getParent() != null) { + activity.getParent().finish(); + } else { + activity.finish(); + } + + if (MainActivityCommon.vmexecutor != null) { + MainActivityCommon.vmexecutor.stopvm(0); + } + } + }).setNegativeButton("No", new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int which) { + } + }).show(); + } + + public static MainActivityCommon.VMStatus checkSaveVMStatus(final Activity activity) { + String pause_state = ""; + if (MainActivityCommon.vmexecutor != null) { + + String command = QmpClient.query_migrate(); + String res = QmpClient.sendCommand(command); + + if (res != null && !res.equals("")) { + //Log.d(TAG, "Migrate status: " + res); + try { + JSONObject resObj = new JSONObject(res); + String resInfo = resObj.getString("return"); + JSONObject resInfoObj = new JSONObject(resInfo); + pause_state = resInfoObj.getString("status"); + } catch (JSONException e) { + if (Config.debug) + Log.e(TAG,e.getMessage()); + //e.printStackTrace(); + } + if (pause_state != null && pause_state.toUpperCase().equals("FAILED")) { + Log.e(TAG, "Error: " + res); + } + } + } + + if (pause_state.toUpperCase().equals("ACTIVE")) { + return MainActivityCommon.VMStatus.Saving; + } else if (pause_state.toUpperCase().equals("COMPLETED")) { + MainActivityCommon.vmexecutor.paused = 1; + + new Handler(Looper.getMainLooper()).postDelayed(new Runnable() { + @Override + public void run() { + promptPausedVM(activity); + } + }, 1000); + return MainActivityCommon.VMStatus.Completed; + + } else if (pause_state.toUpperCase().equals("FAILED")) { + new Handler(Looper.getMainLooper()).postDelayed(new Runnable() { + @Override + public void run() { + pausedErrorVM(activity, null); + } + }, 100); + return MainActivityCommon.VMStatus.Failed; + } + return MainActivityCommon.VMStatus.Unknown; + } + + public static boolean isHostX86_64() { + if(Build.SUPPORTED_64_BIT_ABIS != null) + { + for(int i=0; i< Build.SUPPORTED_64_BIT_ABIS.length ; i++) + if(Build.SUPPORTED_64_BIT_ABIS[i].equals("x86_64")) + return true; + } + return false; + } + + public static boolean isHostX86() { + if(Build.SUPPORTED_32_BIT_ABIS != null) + { + for(int i=0; i< Build.SUPPORTED_32_BIT_ABIS.length ; i++) + if(Build.SUPPORTED_32_BIT_ABIS[i].equals("x86")) + return true; + } + return false; + } + + public static boolean isHostArm() { + if(Build.SUPPORTED_32_BIT_ABIS != null) + { + for(int i=0; i< Build.SUPPORTED_32_BIT_ABIS.length ; i++) + if(Build.SUPPORTED_32_BIT_ABIS[i].equals("armeabi-v7a")) + return true; + } + return false; + } + + public static boolean isHostArmv8() { + if(Build.SUPPORTED_64_BIT_ABIS != null) + { + for(int i=0; i< Build.SUPPORTED_64_BIT_ABIS.length ; i++) + if(Build.SUPPORTED_64_BIT_ABIS[i].equals("arm64-v8a")) + return true; + } + return false; + } + + public static boolean isHost64Bit() { + return Build.SUPPORTED_64_BIT_ABIS!=null && Build.SUPPORTED_64_BIT_ABIS.length > 0 ; + } + + + public static void resetVM(final Activity activity) { + + new AlertDialog.Builder(activity, R.style.MainDialogTheme).setTitle("Reset VM") + .setMessage("To avoid any corrupt data make sure you " + + "have already shutdown the Operating system from within the VM. Continue?") + .setPositiveButton("Yes", new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int which) { + new Thread(new Runnable() { + public void run() { + Log.v(TAG, "VM is reset"); + Machine.onRestartVM(activity); + } + }).start(); + + } + }).setNegativeButton("No", new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int which) { + } + }).show(); + } +} diff --git a/app/src/main/java/com/vectras/qemu/utils/QmpClient.java b/app/src/main/java/com/vectras/qemu/utils/QmpClient.java new file mode 100644 index 0000000..da37113 --- /dev/null +++ b/app/src/main/java/com/vectras/qemu/utils/QmpClient.java @@ -0,0 +1,277 @@ +package com.vectras.qemu.utils; + +import android.net.LocalSocket; +import android.net.LocalSocketAddress; +import android.util.Log; + +import com.vectras.qemu.Config; + +import org.json.JSONObject; + +import java.io.BufferedReader; +import java.io.File; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.PrintWriter; +import java.net.Socket; + +public class QmpClient { + + private static final String TAG = "QmpClient"; + private static String requestCommandMode = "{ \"execute\": \"qmp_capabilities\" }"; + public static boolean allow_external = false; + + public synchronized static String sendCommand(String command) { + String response = null; + int trial=0; + Socket pingSocket = null; + LocalSocket localSocket = null; + PrintWriter out = null; + BufferedReader in = null; + + try { + if(allow_external) { + pingSocket = new Socket(Config.QMPServer, Config.QMPPort); + pingSocket.setSoTimeout(5000); + out = new PrintWriter(pingSocket.getOutputStream(), true); + in = new BufferedReader(new InputStreamReader(pingSocket.getInputStream())); + } else { + localSocket = new LocalSocket(); + String localQMPSocketPath = Config.getLocalQMPSocketPath(); + LocalSocketAddress localSocketAddr = new LocalSocketAddress(localQMPSocketPath, LocalSocketAddress.Namespace.FILESYSTEM); + localSocket.connect(localSocketAddr); + localSocket.setSoTimeout(5000); + out = new PrintWriter(localSocket.getOutputStream(), true); + in = new BufferedReader(new InputStreamReader(localSocket.getInputStream())); + } + + + sendRequest(out, QmpClient.requestCommandMode); + while(true){ + response = getResponse(in); + if(response == null || response.equals("") || trial <10) + break; + + Thread.sleep(1000); + trial++; + } + + sendRequest(out, command); + trial=0; + while((response = getResponse(in)).equals("") && trial < 10){ + Thread.sleep(1000); + trial++; + } + } catch (java.net.ConnectException e) { + Log.w(TAG, "Could not connect to QMP: " + e); + if(Config.debugQmp) + e.printStackTrace(); + } catch(Exception e) { + // TODO Auto-generated catch block + Log.e(TAG, "Error while connecting to QMP: " + e); + if(Config.debugQmp) + e.printStackTrace(); + } finally { + if (out != null) + out.close(); + try { + if (in != null) + in.close(); + if (pingSocket != null) + pingSocket.close(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + } + + return response; + } + + private static void sendRequest(PrintWriter out, String request) { + + if(Config.debugQmp) + Log.i(TAG, "QMP request" + request); + out.println(request); + } + + private static String getResponse(BufferedReader in) throws Exception { + + String line; + StringBuilder stringBuilder = new StringBuilder(""); + + try { + do { + line = in.readLine(); + if (line != null) { + if(Config.debugQmp) + Log.i(TAG, "QMP response: " + line); + JSONObject object = new JSONObject(line); + String returnStr = null; + String errStr = null; + + try { + if(line.contains("return")) + returnStr = object.getString("return"); + } catch (Exception ex) { + if(Config.debugQmp) + ex.printStackTrace(); + } + + if (returnStr != null) { + stringBuilder.append(line); + stringBuilder.append("\n"); + break; + } + + try { + if(line.contains("error")) + errStr = object.getString("error"); + } catch (Exception ex) { + if(Config.debugQmp) + ex.printStackTrace(); + } + + stringBuilder.append(line); + stringBuilder.append("\n"); + + if (errStr != null) { + break; + } + + + } else + break; + } while (true); + } catch (Exception ex) { + Log.e(TAG, "Could not get Response: " + ex.getMessage()); + if(Config.debugQmp) + ex.printStackTrace(); + } + return stringBuilder.toString(); + } + + private static String getQueryMigrateResponse(BufferedReader in) throws Exception { + + String line; + StringBuilder stringBuilder = new StringBuilder(""); + + try { + do { + line = in.readLine(); + if (line != null) { + if(Config.debugQmp) + Log.i(TAG, "QMP query-migrate response: " + line); + JSONObject object = new JSONObject(line); + String returnStr = null; + String errStr = null; + + try { + returnStr = object.getString("return"); + } catch (Exception ex) { + + } + + if (returnStr != null) { + break; + } + + try { + errStr = object.getString("error"); + } catch (Exception ex) { + + } + + stringBuilder.append(line); + stringBuilder.append("\n"); + + if (errStr != null) { + break; + } + + + } else + break; + } while (true); + } catch (Exception ex) { + + } + return stringBuilder.toString(); + } + + public static String migrate(boolean block, boolean inc, String uri) { + + // XXX: Detach should not be used via QMP according to docs + // return "{\"execute\":\"migrate\",\"arguments\":{\"detach\":" + detach + // + ",\"blk\":" + block + ",\"inc\":" + inc + // + ",\"uri\":\"" + uri + "\"},\"id\":\"limbo\"}"; + + // its better not to use block (full disk copy) cause its slow (though + // safer) + // see qmp-commands.hx for more info + return "{\"execute\":\"migrate\",\"arguments\":{\"blk\":" + block + ",\"inc\":" + inc + ",\"uri\":\"" + uri + + "\"},\"id\":\"limbo\"}"; + + } + + public static String changevncpasswd(String passwd) { + + return "{\"execute\": \"change\", \"arguments\": { \"device\": \"vnc\", \"target\": \"password\", \"arg\": \"" + passwd +"\" } }"; + + } + + public static String ejectdev(String dev) { + + return "{ \"execute\": \"eject\", \"arguments\": { \"device\": \""+ dev +"\" } }"; + + } + + public static String changedev(String dev, String value) { + + return "{ \"execute\": \"change\", \"arguments\": { \"device\": \""+dev+"\", \"target\": \"" + value + "\" } }"; + + } + + + + public static String query_migrate() { + return "{ \"execute\": \"query-migrate\" }"; + + } + + public static String save_snapshot(String snapshot_name) { + return "{\"execute\": \"snapshot-create\", \"arguments\": {\"name\": \""+ snapshot_name+"\"} }"; + + } + + public static String query_snapshot() { + return "{ \"execute\": \"query-snapshot-status\" }"; + + } + + public static String stop() { + return "{ \"execute\": \"stop\" }"; + + } + + public static String cont() { + return "{ \"execute\": \"cont\" }"; + + } + + public static String powerDown() { + return "{ \"execute\": \"system_powerdown\" }"; + + } + + public static String reset() { + return "{ \"execute\": \"system_reset\" }"; + + } + + public static String getState() { + return "{ \"execute\": \"query-status\" }"; + + } +} diff --git a/app/src/main/java/com/vectras/qemu/utils/RamInfo.java b/app/src/main/java/com/vectras/qemu/utils/RamInfo.java new file mode 100644 index 0000000..ae29aed --- /dev/null +++ b/app/src/main/java/com/vectras/qemu/utils/RamInfo.java @@ -0,0 +1,38 @@ +package com.vectras.qemu.utils; + +import static android.content.Context.ACTIVITY_SERVICE; + +import android.app.Activity; +import android.app.ActivityManager; +import android.content.SharedPreferences; +import android.preference.PreferenceManager; + +import com.vectras.qemu.MainSettingsManager; + +public class RamInfo { + public static Activity activity; + + public static int safeLongToInt(long l) { + if (l < Integer.MIN_VALUE || l > Integer.MAX_VALUE) { + throw new IllegalArgumentException(l + " cannot be cast to int without changing its value."); + } + return (int) l; + } + + public static int vectrasMemory() { + ActivityManager.MemoryInfo mi = new ActivityManager.MemoryInfo(); + ActivityManager activityManager = (ActivityManager) activity.getSystemService(ACTIVITY_SERVICE); + activityManager.getMemoryInfo(mi); + long freeMem = mi.availMem / 1048576L; + long totalMem = mi.totalMem / 1048576L; + long usedMem = totalMem - freeMem; + int freeRamInt = safeLongToInt(freeMem); + int totalRamInt = safeLongToInt(totalMem); + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity); + if (prefs.getBoolean("customMemory", false)) { + return Integer.parseInt(prefs.getString("memory", String.valueOf(256))); + } else { + return freeRamInt - 100; + } + } +} diff --git a/app/src/main/java/com/vectras/vm/AboutActivity.java b/app/src/main/java/com/vectras/vm/AboutActivity.java new file mode 100644 index 0000000..6169bb5 --- /dev/null +++ b/app/src/main/java/com/vectras/vm/AboutActivity.java @@ -0,0 +1,235 @@ +package com.vectras.vm; + +import android.annotation.SuppressLint; +import android.content.DialogInterface; +import android.content.Intent; +import android.net.Uri; +import android.os.Build; +import android.os.Bundle; + +import com.google.android.gms.ads.AdRequest; +import com.google.android.gms.ads.AdView; +import com.google.android.gms.ads.LoadAdError; +import com.google.android.gms.ads.MobileAds; +import com.google.android.gms.ads.initialization.InitializationStatus; +import com.google.android.gms.ads.initialization.OnInitializationCompleteListener; +import com.google.android.gms.ads.interstitial.InterstitialAd; +import com.google.android.gms.ads.interstitial.InterstitialAdLoadCallback; +import com.vectras.vm.utils.UIUtils; +import com.google.android.material.floatingactionbutton.FloatingActionButton; +import com.google.android.material.snackbar.Snackbar; + +import androidx.annotation.NonNull; +import androidx.appcompat.app.AlertDialog; +import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.widget.Toolbar; + +import android.util.Log; +import android.view.MenuItem; +import android.view.View; +import android.widget.Button; +import android.widget.Toast; + +import com.vectras.vm.R; + +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.net.HttpURLConnection; +import java.net.URL; + +public class AboutActivity extends AppCompatActivity implements View.OnClickListener{ + + Button btn_osl, btn_clog, btn_youtube, btn_github, btn_telegram, btn_instagram, btn_facebook; + String appInfo; + + public String TAG = "AboutActivity"; + private InterstitialAd mInterstitialAd; + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_about); + Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); + setSupportActionBar(toolbar); + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + getSupportActionBar().setDisplayShowHomeEnabled(true); + toolbar.setTitle("About"); + //btn + btn_telegram = (Button) findViewById(R.id.btn_telegram); + btn_youtube = (Button) findViewById(R.id.btn_youtube); + btn_github = (Button) findViewById(R.id.btn_github); + btn_instagram = (Button) findViewById(R.id.btn_instagram); + btn_facebook = (Button) findViewById(R.id.btn_facebook); + btn_osl = (Button) findViewById(R.id.btn_osl); + btn_clog = (Button) findViewById(R.id.btn_changelog); + //onclicklistener + btn_telegram.setOnClickListener(this); + btn_github.setOnClickListener(this); + btn_youtube.setOnClickListener(this); + btn_instagram.setOnClickListener(this); + btn_facebook.setOnClickListener(this); + btn_osl.setOnClickListener(this); + btn_clog.setOnClickListener(this); + + AdView mAdView = findViewById(R.id.adView); + AdRequest adRequest = new AdRequest.Builder().build(); + mAdView.loadAd(adRequest); + new Thread(new Runnable(){ + + public void run(){ + + BufferedReader reader = null; + final StringBuilder builder = new StringBuilder(); + + try { + // Create a URL for the desired page + URL url = new URL(AppConfig.vectrasInfo); //My text file location + //First open the connection + HttpURLConnection conn=(HttpURLConnection) url.openConnection(); + conn.setConnectTimeout(60000); // timing out in a minute + + BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream())); + + //t=(TextView)findViewById(R.id.TextView1); // ideally do this in onCreate() + String str; + while ((str = in.readLine()) != null) { + builder.append(str); + } + in.close(); + } catch (Exception e) { + UIUtils.toastLong(AboutActivity.this, "check your internet connection"); + Log.d("VECTRAS",e.toString()); + } + + //since we are in background thread, to post results we have to go back to ui thread. do the following for that + + runOnUiThread(new Runnable(){ + public void run(){ + appInfo = builder.toString(); // My TextFile has 3 lines + + } + }); + + } + }).start(); + FloatingActionButton fab = findViewById(R.id.fab); + fab.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + Intent i = new Intent(Intent.ACTION_SEND); + i.setType("message/rfc822"); + i.putExtra(Intent.EXTRA_EMAIL , new String[]{"noureldeenelsayed856@gmail.com"}); + i.putExtra(Intent.EXTRA_SUBJECT, "Vectras User: " + Build.BRAND); + i.putExtra(Intent.EXTRA_TEXT , "Device Model: \n" + Build.MODEL + "\n"); + try { + startActivity(Intent.createChooser(i, "Send mail...")); + } catch (android.content.ActivityNotFoundException ex) { + Snackbar.make(view, "There are no email clients installed.", Snackbar.LENGTH_LONG) + .setAction("Action", null).show(); + } + + } + }); + + MobileAds.initialize(this, new OnInitializationCompleteListener() { + @Override + public void onInitializationComplete(InitializationStatus initializationStatus) {} + }); + InterstitialAd.load(this,"ca-app-pub-3568137780412047/4892595373", adRequest, + new InterstitialAdLoadCallback() { + @Override + public void onAdLoaded(@NonNull InterstitialAd interstitialAd) { + // The mInterstitialAd reference will be null until + // an ad is loaded. + mInterstitialAd = interstitialAd; + Log.i(TAG, "onAdLoaded"); + } + + @Override + public void onAdFailedToLoad(@NonNull LoadAdError loadAdError) { + // Handle the error + Log.d(TAG, loadAdError.toString()); + mInterstitialAd = null; + } + }); + if (mInterstitialAd != null) { + mInterstitialAd.show(AboutActivity.this); + } else { + Log.d("TAG", "The interstitial ad wasn't ready yet."); + } + } + + @Override + public boolean onOptionsItemSelected(@NonNull MenuItem item) { + if(item.getItemId()== android.R.id.home){ + finish(); + } + return super.onOptionsItemSelected(item); + } + public static final int TG = R.id.btn_telegram; + public static final int YT = R.id.btn_youtube; + public static final int GT = R.id.btn_github; + public static final int IG = R.id.btn_instagram; + public static final int FB = R.id.btn_facebook; + public static final int CL = R.id.btn_changelog; + public static final int OSL = R.id.btn_osl; + @Override + public void onClick(View v) { + int id = v.getId(); + if (id == TG) { + String tg = "https://t.me/vectras_os"; + Intent f = new Intent(Intent.ACTION_VIEW); + f.setData(Uri.parse(tg)); + startActivity(f); + } else if (id == YT) { + String tw = "https://www.youtube.com/@XOURELDEEN"; + Intent w = new Intent(Intent.ACTION_VIEW); + w.setData(Uri.parse(tw)); + startActivity(w); + } else if (id == GT) { + String gt = AppConfig.vectrasRepo; + Intent g = new Intent(Intent.ACTION_VIEW); + g.setData(Uri.parse(gt)); + startActivity(g); + } else if (id == IG) { + String ig = "https://www.instagram.com/vectrasvm"; + Intent i = new Intent(Intent.ACTION_VIEW); + i.setData(Uri.parse(ig)); + startActivity(i); + } else if (id == FB) { + String fb = "https://www.facebook.com/profile.php?id=61555122773211"; + Intent f = new Intent(Intent.ACTION_VIEW); + f.setData(Uri.parse(fb)); + startActivity(f); + } else if (id == CL) { + AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this, R.style.MainDialogTheme); + alertDialogBuilder.setTitle("Changelog"); + alertDialogBuilder + .setMessage(getString(R.string.app_version)) + .setCancelable(true) + .setIcon(R.mipmap.ic_launcher) + .setNegativeButton("OK", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + } + }); + AlertDialog alertDialog = alertDialogBuilder.create(); + alertDialog.show(); + } else if (id == OSL) { + AlertDialog.Builder alertDialogOSL = new AlertDialog.Builder(this, R.style.MainDialogTheme); + alertDialogOSL.setTitle("APP INFO"); + alertDialogOSL + .setMessage(appInfo) + .setCancelable(true) + .setIcon(R.drawable.round_info_24) + .setNegativeButton("OK", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + } + }); + AlertDialog alertDialogosl = alertDialogOSL.create(); + alertDialogosl.show(); + } + } +} diff --git a/app/src/main/java/com/vectras/vm/AppConfig.java b/app/src/main/java/com/vectras/vm/AppConfig.java new file mode 100644 index 0000000..7a71305 --- /dev/null +++ b/app/src/main/java/com/vectras/vm/AppConfig.java @@ -0,0 +1,34 @@ +package com.vectras.vm; + +import android.os.Environment; +import android.widget.ImageView.ScaleType; + +import java.io.File; +import java.util.Hashtable; + +/** + * + * @author dev + */ +public class AppConfig { + + // App Config + public static final String vectrasWebsite = "https://vectras.netlify.com/"; + public static final String vectrasRaw = "https://raw.githubusercontent.com/epicstudios856/Vectras-windows-emulator/main/"; + public static final String vectrasLicense = vectrasRaw + "LICENSE.md"; + public static final String vectrasPrivacy = vectrasRaw + "PRIVACYANDPOLICY.md"; + public static final String vectrasTerms = vectrasRaw + "TERMSOFSERVICE.md"; + public static final String vectrasInfo = vectrasRaw + "info.md"; + public static final String vectrasRepo = "https://github.com/epicstudios856/Vectras-windows-emulator/tree/main/"; + public static final String updateJson = vectrasRaw + "UpdateConfig.json"; + public static final String blogJson = vectrasRaw + "news_list.json"; + public static final String storeJson = vectrasRaw + "store_list.json"; + public static final String romsJson = vectrasRaw + "roms.json"; + + // App config + public static final String datadirpath = SplashActivity.activity.getExternalFilesDir("data")+"/"; + public static final String sharedFolder = datadirpath + "Vectras/ProgramFiles/"; + public static final String basefiledir = datadirpath + "Vectras/.qemu/"; + public static final String maindirpath = datadirpath + "Vectras/"; + +} diff --git a/app/src/main/java/com/vectras/vm/Blog/AdapterBlog.java b/app/src/main/java/com/vectras/vm/Blog/AdapterBlog.java new file mode 100644 index 0000000..8444ad2 --- /dev/null +++ b/app/src/main/java/com/vectras/vm/Blog/AdapterBlog.java @@ -0,0 +1,98 @@ +package com.vectras.vm.Blog; + +import android.content.Context; +import android.content.Intent; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.view.animation.Animation; +import android.view.animation.AnimationUtils; +import android.widget.ImageView; +import android.widget.TextView; +import androidx.cardview.widget.CardView; +import androidx.fragment.app.FragmentTransaction; +import androidx.recyclerview.widget.RecyclerView; +import com.bumptech.glide.Glide; +import com.vectras.vm.R; +import com.vectras.vm.Fragment.HomeFragment; +import com.vectras.vm.PostActivity; +import java.util.Collections; +import java.util.List; +import com.vectras.vm.MainActivity; + +public class AdapterBlog extends RecyclerView.Adapter { + + private Context context; + private LayoutInflater inflater; + List data = Collections.emptyList(); + DataBlog current; + int currentPos = 0; + + // create constructor to innitilize context and data sent from MainActivity + public AdapterBlog(Context context, List data) { + this.context = context; + inflater = LayoutInflater.from(context); + this.data = data; + } + + // Inflate the layout when viewholder created + @Override + public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { + View view = inflater.inflate(R.layout.container_post, parent, false); + MyHolder holder = new MyHolder(view); + return holder; + } + + // Bind data + @Override + public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { + + // Get current position of item in recyclerview to bind data and assign values from list + MyHolder myHolder = (MyHolder) holder; + final DataBlog current = data.get(position); + myHolder.textTitle.setText(current.postTitle); + myHolder.textDate.setText("Date: " + current.postDate); + Glide.with(MainActivity.activity).load(current.postThumb).into(myHolder.ivThumb); + Animation animation; + animation = AnimationUtils.loadAnimation(MainActivity.activity, android.R.anim.slide_in_left); + animation.setDuration(300); + + myHolder.cdPost.startAnimation(animation); + animation = null; + myHolder.cdPost.setOnClickListener(new View.OnClickListener() { + public void onClick(View view) { + + PostActivity.title = current.postTitle; + PostActivity.content = current.postContent; + PostActivity.date = current.postDate; + PostActivity.thumb = current.postThumb; + MainActivity.activity.startActivity(new Intent(MainActivity.activity, PostActivity.class)); + } + }); + } + + // return total item from List + @Override + public int getItemCount() { + return data.size(); + } + + class MyHolder extends RecyclerView.ViewHolder { + + CardView cdPost; + TextView textTitle; + ImageView ivThumb; + TextView textDate; + + // create constructor to get widget reference + public MyHolder(View itemView) { + super(itemView); + cdPost = (CardView) itemView.findViewById(R.id.cdPost); + textTitle = (TextView) itemView.findViewById(R.id.textTitle); + ivThumb = (ImageView) itemView.findViewById(R.id.ivThumb); + textDate = (TextView) itemView.findViewById(R.id.textDate); + } + + } + +} diff --git a/app/src/main/java/com/vectras/vm/Blog/DataBlog.java b/app/src/main/java/com/vectras/vm/Blog/DataBlog.java new file mode 100644 index 0000000..f3e17e0 --- /dev/null +++ b/app/src/main/java/com/vectras/vm/Blog/DataBlog.java @@ -0,0 +1,9 @@ +package com.vectras.vm.Blog; + +public class DataBlog { + + public String postThumb; + public String postTitle; + public String postContent; + public String postDate; +} diff --git a/app/src/main/java/com/vectras/vm/Fragment/ControlersOptionsFragment.java b/app/src/main/java/com/vectras/vm/Fragment/ControlersOptionsFragment.java new file mode 100644 index 0000000..9f51809 --- /dev/null +++ b/app/src/main/java/com/vectras/vm/Fragment/ControlersOptionsFragment.java @@ -0,0 +1,50 @@ +package com.vectras.vm.Fragment; + +import android.app.Dialog; +import android.graphics.drawable.ColorDrawable; +import android.os.Bundle; + +import androidx.appcompat.app.AlertDialog; +import androidx.fragment.app.DialogFragment; +import androidx.fragment.app.Fragment; + +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.view.Window; + +import com.vectras.qemu.MainSettingsManager; +import com.vectras.vm.R; +public class ControlersOptionsFragment extends DialogFragment { + + @Override + public Dialog onCreateDialog(Bundle savedInstanceState) { + final Dialog alertDialog = new Dialog(getActivity(), R.style.MainDialogTheme); + alertDialog.requestWindowFeature(Window.FEATURE_NO_TITLE); + alertDialog.getWindow().setBackgroundDrawable(new ColorDrawable(android.graphics.Color.TRANSPARENT)); + alertDialog.setContentView(R.layout.fragment_controlers_options); + alertDialog.findViewById(R.id.gamepadBtn).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + MainSettingsManager.setControlMode(getActivity(), "G"); + alertDialog.cancel(); + } + }); + alertDialog.findViewById(R.id.desktopBtn).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + MainSettingsManager.setControlMode(getActivity(), "D"); + alertDialog.cancel(); + } + }); + alertDialog.findViewById(R.id.hideBtn).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + MainSettingsManager.setControlMode(getActivity(), "H"); + alertDialog.cancel(); + } + }); + alertDialog.show(); + return alertDialog; + } +} \ No newline at end of file diff --git a/app/src/main/java/com/vectras/vm/Fragment/DialogSettingsFragment.java b/app/src/main/java/com/vectras/vm/Fragment/DialogSettingsFragment.java new file mode 100644 index 0000000..2eac5a0 --- /dev/null +++ b/app/src/main/java/com/vectras/vm/Fragment/DialogSettingsFragment.java @@ -0,0 +1,46 @@ +package com.vectras.vm.Fragment; + +import android.os.Bundle; + +import androidx.fragment.app.Fragment; + +import android.view.LayoutInflater; +import android.view.MenuItem; +import android.view.View; +import android.view.ViewGroup; + +import com.google.android.material.navigation.NavigationView; +import com.vectras.vm.R; + +public class DialogSettingsFragment extends Fragment { + + public View view; + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + // Inflate the layout for this fragment + view = inflater.inflate(R.layout.content_settings_dialog, container, false); + + NavigationView navView = view.findViewById(R.id.navView); + View fragment = view.findViewById(R.id.fragment); + navView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() { + + // This method will trigger on item Click of navigation menu + @Override + public boolean onNavigationItemSelected(MenuItem menuItem) { + //Check to see which item was being clicked and perform appropriate action + int id = menuItem.getItemId(); + if (id == R.id.uiInterface) { + + } + return false; + } + }); + return view; + } +} \ No newline at end of file diff --git a/app/src/main/java/com/vectras/vm/Fragment/HomeFragment.java b/app/src/main/java/com/vectras/vm/Fragment/HomeFragment.java new file mode 100644 index 0000000..332fc79 --- /dev/null +++ b/app/src/main/java/com/vectras/vm/Fragment/HomeFragment.java @@ -0,0 +1,163 @@ +package com.vectras.vm.Fragment; + +import android.app.ProgressDialog; +import android.content.Context; +import android.content.Intent; +import android.net.ConnectivityManager; +import android.net.Network; +import android.net.NetworkInfo; +import android.os.AsyncTask; +import android.net.NetworkRequest; +import android.os.Bundle; +import android.telephony.NetworkScanRequest; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.Toast; +import androidx.fragment.app.Fragment; +import androidx.recyclerview.widget.GridLayoutManager; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; +import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; + +import com.vectras.vm.RomsManagerActivity; +import com.vectras.vm.MainRoms.AdapterMainRoms; +import com.vectras.vm.MainRoms.DataMainRoms; +import com.vectras.vm.R; +import com.vectras.vm.Blog.AdapterBlog; +import com.vectras.vm.Blog.DataBlog; +import com.vectras.vm.AppConfig; +import com.vectras.vm.MainActivity; +import com.vectras.vm.utils.FileUtils; +import com.vectras.vm.utils.UIUtils; +import java.io.BufferedReader; +import java.io.File; +import java.io.IOException; +import java.net.HttpURLConnection; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.io.InputStreamReader; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.ArrayList; +import java.util.List; +import javax.net.ssl.HttpsURLConnection; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +public class HomeFragment extends Fragment { + + View view; + public static RecyclerView mRVMainRoms; + public static LinearLayout romsLayout; + public static AdapterMainRoms mMainAdapter; + public MainActivity activity; + public static JSONArray jArray; + public static List data; + + /*private ImageButton mStop; + private ImageButton mRestart;*/ + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + // TODO Auto-generated method stub + + activity = MainActivity.activity; + + view = inflater.inflate(R.layout.home_fragment, container, false); + + romsLayout = view.findViewById(R.id.romsLayout); + + SwipeRefreshLayout refreshRoms = view.findViewById(R.id.refreshRoms); + + refreshRoms.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { + @Override + public void onRefresh() { + data=new ArrayList<>(); + + try { + + jArray = new JSONArray(FileUtils.readFromFile(MainActivity.activity, new File(AppConfig.maindirpath + + "roms-data.json"))); + + // Extract data from json and store into ArrayList as class objects + for(int i=0;i(); + + try { + + jArray = new JSONArray(FileUtils.readFromFile(MainActivity.activity, new File(AppConfig.maindirpath + + "roms-data.json"))); + + // Extract data from json and store into ArrayList as class objects + for(int i=0;i[E] "+logLine+""); + VectrasStatus.logError("[W] "+logLine2+""); + } + } catch (IOException e) { + throw new RuntimeException(e); + } + } + }); + } + }; + _timer.scheduleAtFixedRate(t, (int) (0), (int) (100)); + } catch (IOException e) { + Toast.makeText(activity, "There was an error: " + Log.getStackTraceString(e), Toast.LENGTH_LONG).show(); + e.printStackTrace(); + } + + return view; + } + +} diff --git a/app/src/main/java/com/vectras/vm/Fragment/UiSettingsFragment.java b/app/src/main/java/com/vectras/vm/Fragment/UiSettingsFragment.java new file mode 100644 index 0000000..23894f4 --- /dev/null +++ b/app/src/main/java/com/vectras/vm/Fragment/UiSettingsFragment.java @@ -0,0 +1,27 @@ +package com.vectras.vm.Fragment; + +import android.os.Bundle; + +import androidx.fragment.app.Fragment; + +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import com.vectras.vm.R; + +public class UiSettingsFragment extends Fragment { + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + // Inflate the layout for this fragment + return inflater.inflate(R.layout.fragment_ui_settings, container, false); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/vectras/vm/ImagePrvActivity.java b/app/src/main/java/com/vectras/vm/ImagePrvActivity.java new file mode 100644 index 0000000..e7e9b97 --- /dev/null +++ b/app/src/main/java/com/vectras/vm/ImagePrvActivity.java @@ -0,0 +1,22 @@ +package com.vectras.vm; + +import android.os.Bundle; +import android.widget.ImageView; + +import androidx.appcompat.app.AppCompatActivity; + +import com.bumptech.glide.Glide; +import com.vectras.vm.R; + +public class ImagePrvActivity extends AppCompatActivity { + public static String linkIv; + public ImageView ivPrv; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.iv_prv); + ivPrv = findViewById(R.id.ivPrv); + Glide.with(this).load(linkIv).into(ivPrv); + } +} diff --git a/app/src/main/java/com/vectras/vm/MainActivity.java b/app/src/main/java/com/vectras/vm/MainActivity.java new file mode 100644 index 0000000..e1d6f44 --- /dev/null +++ b/app/src/main/java/com/vectras/vm/MainActivity.java @@ -0,0 +1,593 @@ +package com.vectras.vm; + +import static android.os.Build.VERSION.SDK_INT; + +import android.app.Activity; +import android.app.ActivityManager; +import android.app.Dialog; +import android.content.Context; +import android.content.DialogInterface; +import android.content.Intent; +import android.content.SharedPreferences; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; +import android.net.Uri; +import android.os.Build; +import android.os.Bundle; +import android.os.Handler; +import android.os.Looper; +import android.preference.PreferenceManager; +import android.text.Html; +import android.util.Log; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.view.animation.Animation; +import android.view.animation.AnimationUtils; +import android.widget.Button; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.ProgressBar; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.appcompat.app.ActionBarDrawerToggle; +import androidx.appcompat.app.AlertDialog; +import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.widget.Toolbar; +import androidx.core.view.GravityCompat; +import androidx.drawerlayout.widget.DrawerLayout; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; +import androidx.viewpager.widget.ViewPager; + +import com.bumptech.glide.Glide; +import com.google.android.gms.ads.LoadAdError; +import com.google.android.gms.ads.MobileAds; +import com.google.android.gms.ads.initialization.InitializationStatus; +import com.google.android.gms.ads.initialization.OnInitializationCompleteListener; +import com.google.android.gms.ads.interstitial.InterstitialAd; +import com.google.android.gms.ads.interstitial.InterstitialAdLoadCallback; +import com.google.android.material.bottomappbar.BottomAppBar; +import com.google.android.material.button.MaterialButton; +import com.google.android.material.color.DynamicColors; +import com.google.android.material.color.utilities.DynamicColor; +import com.google.firebase.auth.FirebaseAuth; +import com.google.firebase.auth.FirebaseUser; +import com.google.firebase.database.FirebaseDatabase; +import com.vectras.qemu.Config; +import com.vectras.qemu.MainActivityCommon; +import com.vectras.qemu.MainService; +import com.vectras.qemu.MainSettingsManager; +import com.vectras.qemu.jni.StartVM; +import com.vectras.qemu.utils.FileUtils; +import com.vectras.vm.Fragment.HomeFragment; +import com.vectras.vm.Fragment.LoggerFragment; +import com.vectras.vm.logger.VectrasStatus; +import com.vectras.vm.utils.AppUpdater; +import com.vectras.qemu.utils.FileInstaller; +import com.vectras.qemu.utils.RamInfo; +import com.google.android.gms.ads.AdRequest; +import com.google.android.gms.ads.AdView; +import com.google.android.material.appbar.AppBarLayout; +import com.google.android.material.bottomnavigation.BottomNavigationView; +import com.google.android.material.floatingactionbutton.FloatingActionButton; +import com.google.android.material.navigation.NavigationView; + +import org.json.JSONException; +import org.json.JSONObject; + +import java.net.InetAddress; +import java.net.NetworkInterface; +import java.net.SocketException; +import java.util.Enumeration; +import java.util.Objects; +import java.util.TimerTask; +import java.util.Timer; + +public class MainActivity extends AppCompatActivity { + + private static Handler MAIN_HANDLER = new Handler(Looper.getMainLooper()); + public static final String TAG = "Main Activity"; + // Static + public static final String CREDENTIAL_SHARED_PREF = "settings_prefs"; + + public static MainActivity activity = null; + //private FirebaseAuth mAuth; + public DrawerLayout mainDrawer; + public Toolbar mainToolbar; + public static TextView totalRam; + public static TextView usedRam; + public static TextView freeRam; + public static TextView ipTxt; + private Timer _timer = new Timer(); + private TimerTask t; + public ViewPager viewPager; + MenuItem prevMenuItem; + int pager_number = 2; + private InterstitialAd mInterstitialAd; + private AdRequest adRequest; + public static AppBarLayout appbar; + + public static void UIAlert(String title, String body, Activity activity) { + AlertDialog ad; + ad = new AlertDialog.Builder(activity, R.style.MainDialogTheme).create(); + ad.setTitle(title); + ad.setMessage(body); + ad.setButton(Dialog.BUTTON_POSITIVE, "OK", new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int which) { + return; + } + }); + ad.show(); + } + + // This is easier: traverse the interfaces and get the local IPs + public static String getLocalIpAddress() { + try { + for (Enumeration en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements(); ) { + NetworkInterface intf = en.nextElement(); + for (Enumeration enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements(); ) { + InetAddress inetAddress = enumIpAddr.nextElement(); + if (!inetAddress.isLoopbackAddress() && inetAddress.getHostAddress().toString().contains(".")) { + return inetAddress.getHostAddress().toString(); + } + } + } + } catch (SocketException ex) { + ex.printStackTrace(); + } + return null; + } + + /** + * Called when the activity is first created. + */ + @Override + public void onCreate(Bundle savedInstanceState) { + + super.onCreate(savedInstanceState); + MainActivityCommon.activity = this; + MainActivityCommon.clearNotifications(); + MainActivityCommon.setupFolders(); + MainActivityCommon.setupStrictMode(); + MainActivityCommon.execTimer(); + MainActivityCommon.checkAndLoadLibs(); + Config.logFilePath = Config.cacheDir + "/vectras/vectras-log.txt"; + activity = this; + this.setContentView(R.layout.main); + this.setupWidgets(); + initNavigationMenu(); + FileInstaller.installFiles(activity, false); + + //updateApp(true); + //mAuth = FirebaseAuth.getInstance(); + } + + public static PackageInfo getAppInfo(Context context) { + try { + return context.getPackageManager().getPackageInfo(context.getPackageName(), 0); + } catch (PackageManager.NameNotFoundException e) { + throw new RuntimeException(e); + } + } + + public void updateApp(final boolean showDialog) { + new AppUpdater(this, new AppUpdater.OnUpdateListener() { + @Override + public void onUpdateListener(String result) { + try { + if (!result.contains("Error on getting data")) { + final JSONObject obj = new JSONObject(result); + PackageInfo pinfo = getAppInfo(getApplicationContext()); + int versionCode = pinfo.versionCode; + if (versionCode < obj.getInt("versionCode")) { + AlertDialog.Builder alert = new AlertDialog.Builder(activity, R.style.MainDialogTheme); + alert.setTitle("Install the latest version") + .setMessage(Html.fromHtml(obj.getString("Message") + "

update size:
" + obj.getString("size"))) + .setCancelable(obj.getBoolean("cancellable")) + .setNegativeButton("Update", new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int id) { + try { + startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(obj.getString("url")))); + } catch (JSONException e) { + + } + } + }).show(); + + } + } else if (result.contains("Error on getting data") && showDialog) { + errorUpdateDialog(result); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + }).start(showDialog); + } + + private void errorUpdateDialog(String error) { + VectrasStatus.logInfo(String.format(error)); + } + + private MenuItem vectrasInfo; + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + // Inflate the menu; this adds items to the action bar if it is present. + getMenuInflater().inflate(R.menu.home_toolbar_menu, menu); + vectrasInfo = menu.findItem(R.id.vectrasInfo); + return true; + + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + + // Menu items + int id = item.getItemId(); + if (id == R.id.vectrasInfo) { + appbar = findViewById(R.id.appbar); + if (appbar.getTop() < 0) + appbar.setExpanded(true); + else + appbar.setExpanded(false); + + } else if (id == R.id.installRoms) { + startActivity(new Intent(MainActivity.activity, RomsManagerActivity.class)); + } + + return super.onOptionsItemSelected(item); + } + + private void initNavigationMenu() { + BottomNavigationView bottomNavigationView = (BottomNavigationView) findViewById(R.id.bNav); + + bottomNavigationView + .setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() { + @Override + public boolean onNavigationItemSelected(@NonNull MenuItem item) { + int id = item.getItemId(); + if (id == R.id.menu_home) { + viewPager.setCurrentItem(0); + } else if (id == R.id.menu_logger) { + viewPager.setCurrentItem(1); + } + return false; + } + }); + } + + public class MyAdapter extends FragmentPagerAdapter { + + MyAdapter(FragmentManager fm) { + super(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT); + } + + @Override + public Fragment getItem(int position) { + + switch (position) { + case 0: + return new HomeFragment(); + case 1: + return new LoggerFragment(); + } + return null; + } + + @Override + public int getCount() { + return pager_number; + } + } + + public static LinearLayout extVncLayout; + public MaterialButton stopBtn; + FirebaseAuth mAuth; + FirebaseUser mCurrentUser; + + // Setting up the UI + public void setupWidgets() { + extVncLayout = findViewById(R.id.extVnc); + stopBtn = findViewById(R.id.stopBtn); + stopBtn.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + MainActivityCommon.onStopButton(true); + } + }); + viewPager = findViewById(R.id.viewPager); + viewPager.setAdapter(new MyAdapter(getSupportFragmentManager())); + viewPager.setOffscreenPageLimit(pager_number); + final BottomNavigationView bottomNavigationView = (BottomNavigationView) findViewById(R.id.bNav); + viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { + @Override + public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { + } + + @Override + public void onPageSelected(int position) { + if (prevMenuItem != null) { + prevMenuItem.setChecked(false); + } else { + bottomNavigationView.getMenu().getItem(0).setChecked(false); + } + bottomNavigationView.getMenu().getItem(position).setChecked(true); + prevMenuItem = bottomNavigationView.getMenu().getItem(position); + } + + @Override + public void onPageScrollStateChanged(int state) { + + } + }); + + appbar = findViewById(R.id.appbar); + appbar.setExpanded(false); + mainToolbar = (Toolbar) findViewById(R.id.toolbar); + setSupportActionBar(mainToolbar); + mainDrawer = (DrawerLayout) findViewById(R.id.drawer_layout); + ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this, mainDrawer, mainToolbar, + R.string.navigation_drawer_open, R.string.navigation_drawer_close); + mainDrawer.setDrawerListener(toggle); + toggle.syncState(); + + NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view); + + View headerView = navigationView.getHeaderView(0); + mAuth = FirebaseAuth.getInstance(); + mCurrentUser = mAuth.getCurrentUser(); + assert mCurrentUser != null; + String name = mCurrentUser.getDisplayName(); + String email = mCurrentUser.getEmail(); + Uri picture = mCurrentUser.getPhotoUrl(); + TextView navUsername = (TextView) headerView.findViewById(R.id.usernameTxt); + navUsername.setText(name); + TextView navEmail = (TextView) headerView.findViewById(R.id.emailTxt); + navEmail.setText(email); + TextView viewProfile = (TextView) headerView.findViewById(R.id.viewProfile); + + ImageView ivProfile = (ImageView) headerView.findViewById(R.id.profilePic2); + + viewProfile.setOnClickListener(new View.OnClickListener() { + public void onClick(View view) { + + startActivity(new Intent(activity, ProfileActivity.class)); + + } + }); + + //Setting Navigation View Item Selected Listener to handle the item click of the navigation menu + navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() { + + // This method will trigger on item Click of navigation menu + @Override + public boolean onNavigationItemSelected(MenuItem menuItem) { + //Closing drawer on item click + mainDrawer.closeDrawers(); + + //Check to see which item was being clicked and perform appropriate action + int id = menuItem.getItemId(); + if (id == R.id.navigation_item_info) { + startActivity(new Intent(activity, AboutActivity.class)); + } else if (id == R.id.navigation_item_website) { + String tw = AppConfig.vectrasWebsite; + Intent w = new Intent(Intent.ACTION_VIEW); + w.setData(Uri.parse(tw)); + startActivity(w); + } else if (id == R.id.navigation_item_view_logs) { + FileUtils.viewVectrasLog(activity); + } else if (id == R.id.navigation_item_settings) { + startActivity(new Intent(activity, MainSettingsManager.class)); + } else if (id == R.id.navigation_item_store) { + startActivity(new Intent(activity, StoreActivity.class)); + } + return false; + } + }); + + ipTxt = findViewById(R.id.ipTxt); + + ActivityManager.MemoryInfo mi = new ActivityManager.MemoryInfo(); + ActivityManager activityManager = (ActivityManager) getSystemService(ACTIVITY_SERVICE); + activityManager.getMemoryInfo(mi); + + long freeMem = mi.availMem / 1048576L; + long totalMem = mi.totalMem / 1048576L; + long usedMem = totalMem - freeMem; + int freeRamInt = safeLongToInt(freeMem); + int totalRamInt = safeLongToInt(totalMem); + ipTxt.setText("Local Ip Address: " + getLocalIpAddress()); + + SharedPreferences credentials = activity.getSharedPreferences(CREDENTIAL_SHARED_PREF, Context.MODE_PRIVATE); + + totalRam = findViewById(R.id.totalRam); + usedRam = findViewById(R.id.usedRam); + freeRam = findViewById(R.id.freeRam); + + ipTxt.setVisibility(View.GONE); + String vectrasMemory = String.valueOf(RamInfo.vectrasMemory()); + t = new TimerTask() { + @Override + public void run() { + runOnUiThread(new Runnable() { + @Override + public void run() { + ActivityManager.MemoryInfo miI = new ActivityManager.MemoryInfo(); + ActivityManager activityManagerr = (ActivityManager) getSystemService(ACTIVITY_SERVICE); + activityManagerr.getMemoryInfo(miI); + long freeMemory = miI.availMem / 1048576L; + long totalMemory = miI.totalMem / 1048576L; + long usedMemory = totalMemory - freeMemory; + + totalRam.setText("Total Memory: " + totalMemory + " MB"); + usedRam.setText("Used Memory: " + usedMemory + " MB"); + freeRam.setText("Free Memory: " + freeMemory + " MB (" + vectrasMemory + " used)"); + ProgressBar progressBar = findViewById(R.id.progressBar); + progressBar.setMax((int) totalMemory); + if (SDK_INT >= Build.VERSION_CODES.N) { + progressBar.setProgress((int) usedMemory, true); + } else { + progressBar.setProgress((int) usedMemory); + } + } + }); + } + }; + _timer.scheduleAtFixedRate(t, (int) (0), (int) (1000)); + + AdView mAdView = findViewById(R.id.adView); + adRequest = new AdRequest.Builder().build(); + mAdView.loadAd(adRequest); + + MobileAds.initialize(this, new OnInitializationCompleteListener() { + @Override + public void onInitializationComplete(InitializationStatus initializationStatus) { + } + }); + if (MainSettingsManager.getPromptUpdateVersion(activity)) + updateApp(true); + /*FirebaseUser user = mAuth.getCurrentUser(); + TextView usernameTxt = findViewById(R.id.usernameTxt); + TextView emailTxt = findViewById(R.id.emailTxt); + ImageView profilePic = findViewById(R.id.profilePic); + if (user != null) { + // Name, email address, and profile photo Url + String name = user.getDisplayName(); + String email = user.getEmail(); + Uri photoUrl = user.getPhotoUrl(); + + // Check if user's email is verified + boolean emailVerified = user.isEmailVerified(); + + // The user's ID, unique to the Firebase project. Do NOT use this value to + // authenticate with your backend server, if you have one. Use + // FirebaseUser.getIdToken() instead. + String uid = user.getUid(); + + usernameTxt.setText(name); + emailTxt.setText(email); + if (photoUrl != null) + Glide.with(activity).load(photoUrl.toString()).into(profilePic); + }*/ + } + + public static int safeLongToInt(long l) { + if (l < Integer.MIN_VALUE || l > Integer.MAX_VALUE) { + throw new IllegalArgumentException(l + " cannot be cast to int without changing its value."); + } + return (int) l; + } + + @Override + public void onBackPressed() { + DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout); + if (drawer.isDrawerOpen(GravityCompat.START)) { + drawer.closeDrawer(GravityCompat.START); + } else { + super.onBackPressed(); + } + } + + private void goToURL(String url) { + + Intent i = new Intent(Intent.ACTION_VIEW); + i.setData(Uri.parse(url)); + activity.startActivity(i); + + } + + @Override + public void onStop() { + super.onStop(); + } + + @Override + public void onDestroy() { + super.onDestroy(); + MainActivityCommon.stopTimeListener(); + + } + + @Override + public void onStart() { + super.onStart(); + InterstitialAd.load(this, "ca-app-pub-3568137780412047/7745973511", adRequest, + new InterstitialAdLoadCallback() { + @Override + public void onAdLoaded(@NonNull InterstitialAd interstitialAd) { + // The mInterstitialAd reference will be null until + // an ad is loaded. + mInterstitialAd = interstitialAd; + Log.i(TAG, "onAdLoaded"); + } + + @Override + public void onAdFailedToLoad(@NonNull LoadAdError loadAdError) { + // Handle the error + Log.d(TAG, loadAdError.toString()); + mInterstitialAd = null; + } + }); + if (mInterstitialAd != null) { + mInterstitialAd.show(MainActivity.this); + } else { + Log.d("TAG", "The interstitial ad wasn't ready yet."); + } + } + + public void onPause() { + super.onPause(); + MainActivityCommon.stopTimeListener(); + } + + public boolean loaded = false; + + public void onResume() { + super.onResume(); + assert mCurrentUser != null; + String name = mCurrentUser.getDisplayName(); + String email = mCurrentUser.getEmail(); + Uri picture = mCurrentUser.getPhotoUrl(); + NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view); + View headerView = navigationView.getHeaderView(0); + TextView navUsername = (TextView) headerView.findViewById(R.id.usernameTxt); + navUsername.setText(name); + TextView navEmail = (TextView) headerView.findViewById(R.id.emailTxt); + navEmail.setText(email); + ImageView ivProfile = (ImageView) headerView.findViewById(R.id.profilePic2); + if (MainService.isRunning && Objects.equals(Config.ui, "VNC")) { + MainActivityCommon.startvnc(); + } + MainActivityCommon.execTimer(); + + InterstitialAd.load(this, "ca-app-pub-3568137780412047/7745973511", adRequest, + new InterstitialAdLoadCallback() { + @Override + public void onAdLoaded(@NonNull InterstitialAd interstitialAd) { + // The mInterstitialAd reference will be null until + // an ad is loaded. + mInterstitialAd = interstitialAd; + Log.i(TAG, "onAdLoaded"); + } + + @Override + public void onAdFailedToLoad(@NonNull LoadAdError loadAdError) { + // Handle the error + Log.d(TAG, loadAdError.toString()); + mInterstitialAd = null; + } + }); + if (mInterstitialAd != null && !loaded && !MainService.isRunning) { + mInterstitialAd.show(MainActivity.this); + loaded = true; + } else { + Log.d("TAG", "The interstitial ad wasn't ready yet."); + } + } + + +} diff --git a/app/src/main/java/com/vectras/vm/MainRoms/AdapterMainRoms.java b/app/src/main/java/com/vectras/vm/MainRoms/AdapterMainRoms.java new file mode 100644 index 0000000..c3e68fc --- /dev/null +++ b/app/src/main/java/com/vectras/vm/MainRoms/AdapterMainRoms.java @@ -0,0 +1,190 @@ +package com.vectras.vm.MainRoms; + +import android.app.Dialog; +import android.app.ProgressDialog; +import android.content.Context; +import android.content.DialogInterface; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.graphics.Color; +import android.graphics.drawable.ColorDrawable; +import android.view.Gravity; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.view.Window; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.appcompat.app.AlertDialog; +import androidx.cardview.widget.CardView; +import androidx.recyclerview.widget.GridLayoutManager; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.vectras.qemu.Config; +import com.vectras.qemu.MainActivityCommon; +import com.vectras.qemu.MainService; +import com.vectras.qemu.MainSettingsManager; +import com.vectras.qemu.jni.StartVM; +import com.vectras.qemu.utils.Machine; +import com.vectras.vm.AppConfig; +import com.vectras.vm.Fragment.HomeFragment; +import com.vectras.vm.MainActivity; +import com.vectras.vm.R; +import com.vectras.vm.utils.UIUtils; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.io.Writer; +import java.util.Collections; +import java.util.List; +import java.util.Objects; +import java.util.Timer; +import java.util.TimerTask; + +public class AdapterMainRoms extends RecyclerView.Adapter { + + private Context context; + private LayoutInflater inflater; + public List data = Collections.emptyList(); + int currentPos = 0; + private int mSelectedItem = -1; + + // create constructor to innitilize context and data sent from MainActivity + public AdapterMainRoms(Context context, List data) { + this.context = context; + inflater = LayoutInflater.from(context); + this.data = data; + } + + // Inflate the layout when viewholder created + @Override + public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { + View view = inflater.inflate(R.layout.container_main_roms, parent, false); + MyHolder holder = new MyHolder(view); + return holder; + } + + // Bind data + @Override + public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) { + + // Get current position of item in recyclerview to bind data and assign values from list + final MyHolder myHolder = (MyHolder) holder; + final DataMainRoms current = data.get(position); + myHolder.textName.setText(current.itemName); + Bitmap bmImg = BitmapFactory.decodeFile(current.itemIcon); + myHolder.ivIcon.setImageBitmap(bmImg); + + myHolder.cdRoms.setOnClickListener(new View.OnClickListener() { + public void onClick(View view) { + MainActivityCommon.setupNativeLibs(); + Config.hda_path = current.itemPath; + Config.extra_params = current.itemExtra; + Thread thread = new Thread(new Runnable() { + public void run() { + if (!Config.loadNativeLibsEarly && !Config.loadNativeLibsMainThread) { + MainActivityCommon.setupNativeLibs(); + } + MainActivityCommon.onStartButton(); + } + }); + thread.setPriority(Thread.MIN_PRIORITY); + thread.start(); + + } + }); + myHolder.cdRoms.setOnLongClickListener(new View.OnLongClickListener() { + @Override + public boolean onLongClick(View v) { + showDialog(current.itemName, current.itemPath, current.itemIcon); + return false; + } + }); + } + + private void showDialog(String title, String path, String pathIcon) { + + final Dialog dialog = new Dialog(MainActivity.activity, R.style.MainDialogTheme); + dialog.requestWindowFeature(Window.FEATURE_NO_TITLE); + dialog.setContentView(R.layout.rom_options_layout); + + LinearLayout removeLayout = dialog.findViewById(R.id.layoutRemove); + + removeLayout.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + AlertDialog ad; + ad = new AlertDialog.Builder(MainActivity.activity, R.style.MainDialogTheme).create(); + ad.setTitle("Remove " + title); + ad.setMessage("Are you sure?"); + ad.setButton(Dialog.BUTTON_NEGATIVE, "REMOVE " + title, new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int which) { + File file = new File(path); + file.delete(); + File fileIcon = new File(pathIcon); + fileIcon.delete(); + + HomeFragment.mMainAdapter = new AdapterMainRoms(MainActivity.activity, HomeFragment.data); + HomeFragment.data.remove(currentPos); + HomeFragment.mRVMainRoms.setAdapter(HomeFragment.mMainAdapter); + HomeFragment.mRVMainRoms.setLayoutManager(new GridLayoutManager(MainActivity.activity, 2)); + HomeFragment.jArray.remove(currentPos); + try { + Writer output = null; + File jsonFile = new File(AppConfig.maindirpath + "roms-data" + ".json"); + output = new BufferedWriter(new FileWriter(jsonFile)); + output.write(HomeFragment.jArray.toString().replace("\\", "").replace("//", "/")); + output.close(); + } catch (Exception e) { + UIUtils.toastLong(MainActivity.activity, e.toString()); + } + UIUtils.toastLong(MainActivity.activity, title + " are removed successfully!"); + return; + } + }); + ad.setButton(Dialog.BUTTON_POSITIVE, "CANCEL", new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int which) { + return; + } + }); + ad.show(); + dialog.dismiss(); + } + }); + + dialog.show(); + dialog.getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); + dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT)); + dialog.getWindow().getAttributes().windowAnimations = R.style.DialogAnimation; + dialog.getWindow().setGravity(Gravity.BOTTOM); + + } + + // return total item from List + @Override + public int getItemCount() { + return data.size(); + } + + class MyHolder extends RecyclerView.ViewHolder { + + CardView cdRoms; + TextView textName; + ImageView ivIcon; + + // create constructor to get widget reference + public MyHolder(View itemView) { + super(itemView); + cdRoms = (CardView) itemView.findViewById(R.id.cdItem); + textName = (TextView) itemView.findViewById(R.id.textName); + ivIcon = (ImageView) itemView.findViewById(R.id.ivIcon); + } + + } + +} diff --git a/app/src/main/java/com/vectras/vm/MainRoms/DataMainRoms.java b/app/src/main/java/com/vectras/vm/MainRoms/DataMainRoms.java new file mode 100644 index 0000000..75506cd --- /dev/null +++ b/app/src/main/java/com/vectras/vm/MainRoms/DataMainRoms.java @@ -0,0 +1,7 @@ +package com.vectras.vm.MainRoms; +public class DataMainRoms { + public String itemIcon; + public String itemName; + public String itemPath; + public String itemExtra; +} diff --git a/app/src/main/java/com/vectras/vm/PostActivity.java b/app/src/main/java/com/vectras/vm/PostActivity.java new file mode 100644 index 0000000..fe68b3e --- /dev/null +++ b/app/src/main/java/com/vectras/vm/PostActivity.java @@ -0,0 +1,150 @@ +package com.vectras.vm; + +import android.text.Html; +import android.util.Log; +import android.view.MenuItem; +import android.view.View; +import android.widget.ImageView; + +import androidx.annotation.NonNull; +import androidx.appcompat.widget.Toolbar; + +import com.bumptech.glide.Glide; +import com.google.android.gms.ads.AdRequest; +import com.google.android.gms.ads.AdView; +import com.google.android.gms.ads.LoadAdError; +import com.google.android.gms.ads.MobileAds; +import com.google.android.gms.ads.initialization.InitializationStatus; +import com.google.android.gms.ads.initialization.OnInitializationCompleteListener; +import com.google.android.gms.ads.interstitial.InterstitialAd; +import com.google.android.gms.ads.interstitial.InterstitialAdLoadCallback; +import com.vectras.vm.R; +import com.vectras.vm.utils.UIUtils; + +import android.os.Bundle; + +import androidx.appcompat.app.AppCompatActivity; + +import android.widget.TextView; + +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.net.HttpURLConnection; +import java.net.URL; + +public class PostActivity extends AppCompatActivity { + + private Toolbar tb; + public static TextView postTitle; + public static TextView postContent; + public static TextView postDate; + public static ImageView postThumb; + public static String title, content, contentStr, date, thumb; + + private InterstitialAd mInterstitialAd; + private String TAG = "PostActivity"; + + /** + * Called when the activity is first created. + */ + @Override + public void onCreate(Bundle savedInstanceState) { + + super.onCreate(savedInstanceState); + this.setContentView(R.layout.post_content); + postTitle = findViewById(R.id.postTitle); + postContent = findViewById(R.id.postContent); + postDate = findViewById(R.id.postDate); + postThumb = findViewById(R.id.postThumb); + tb = (Toolbar) findViewById(R.id.toolbar); + setSupportActionBar(tb); + + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + getSupportActionBar().setDisplayShowHomeEnabled(true); + + AdView mAdView = findViewById(R.id.adView); + AdRequest adRequest = new AdRequest.Builder().build(); + mAdView.loadAd(adRequest); + MobileAds.initialize(this, new OnInitializationCompleteListener() { + @Override + public void onInitializationComplete(InitializationStatus initializationStatus) { + } + }); + InterstitialAd.load(this, "ca-app-pub-3568137780412047/7745973511", adRequest, + new InterstitialAdLoadCallback() { + @Override + public void onAdLoaded(@NonNull InterstitialAd interstitialAd) { + // The mInterstitialAd reference will be null until + // an ad is loaded. + mInterstitialAd = interstitialAd; + Log.i(TAG, "onAdLoaded"); + } + + @Override + public void onAdFailedToLoad(@NonNull LoadAdError loadAdError) { + // Handle the error + Log.d(TAG, loadAdError.toString()); + mInterstitialAd = null; + } + }); + postContent.setTextIsSelectable(true); + + Glide.with(this).load(thumb).into(postThumb); + new Thread(new Runnable() { + + public void run() { + + BufferedReader reader = null; + final StringBuilder builder = new StringBuilder(); + + try { + // Create a URL for the desired page + URL url = new URL(content); //My text file location + //First open the connection + HttpURLConnection conn = (HttpURLConnection) url.openConnection(); + conn.setConnectTimeout(60000); // timing out in a minute + + BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream())); + + //t=(TextView)findViewById(R.id.TextView1); // ideally do this in onCreate() + String str; + while ((str = in.readLine()) != null) { + builder.append(str); + } + in.close(); + } catch (Exception e) { + postContent.setText("no internet connection"); + UIUtils.toastLong(PostActivity.this, "check your internet connection"); + Log.d("VECTRAS", e.toString()); + } + + //since we are in background thread, to post results we have to go back to ui thread. do the following for that + + PostActivity.this.runOnUiThread(new Runnable() { + public void run() { + contentStr = builder.toString(); // My TextFile has 3 lines + postContent.setText(Html.fromHtml(contentStr)); + } + }); + + } + }).start(); + postDate.setText(date); + postTitle.setText(title); + } + + @Override + public boolean onOptionsItemSelected(@NonNull MenuItem item) { + if (item.getItemId() == android.R.id.home) { + finish(); + } + return super.onOptionsItemSelected(item); + } + + @Override + public void onBackPressed() { + super.onBackPressed(); + finish(); + } + +} diff --git a/app/src/main/java/com/vectras/vm/ProfileActivity.java b/app/src/main/java/com/vectras/vm/ProfileActivity.java new file mode 100644 index 0000000..e28f63a --- /dev/null +++ b/app/src/main/java/com/vectras/vm/ProfileActivity.java @@ -0,0 +1,195 @@ +package com.vectras.vm; + +import androidx.annotation.NonNull; +import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.widget.Toolbar; + +import android.content.Intent; +import android.graphics.Bitmap; +import android.graphics.drawable.BitmapDrawable; +import android.graphics.drawable.Drawable; +import android.net.Uri; +import android.os.Bundle; +import android.text.Editable; +import android.text.TextWatcher; +import android.view.MenuItem; +import android.view.View; +import android.widget.ImageView; +import android.widget.ProgressBar; +import android.widget.TextView; + +import com.bumptech.glide.Glide; +import com.google.android.gms.tasks.Continuation; +import com.google.android.gms.tasks.OnCompleteListener; +import com.google.android.gms.tasks.OnSuccessListener; +import com.google.android.gms.tasks.Task; +import com.google.android.material.button.MaterialButton; +import com.google.android.material.snackbar.Snackbar; +import com.google.android.material.textfield.TextInputEditText; +import com.google.firebase.auth.FirebaseAuth; +import com.google.firebase.auth.FirebaseUser; +import com.google.firebase.auth.UserProfileChangeRequest; +import com.google.firebase.database.DatabaseReference; +import com.google.firebase.database.FirebaseDatabase; +import com.google.firebase.storage.FirebaseStorage; +import com.google.firebase.storage.StorageReference; +import com.google.firebase.storage.UploadTask; +import com.vectras.qemu.MainService; +import com.vectras.vm.ui.login.SignupActivity; + +import java.io.ByteArrayOutputStream; + +public class ProfileActivity extends AppCompatActivity { + + private ProfileActivity activity; + public TextInputEditText profileUsername; + public MaterialButton saveBtn; + FirebaseAuth mAuth; + FirebaseUser mCurrentUser; + private DatabaseReference newUser; + public Uri profileUri; + + public ImageView profilePic; + + public ProgressBar loadingPb; + + private Uri imgUri = null; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_profile); + activity = this; + Toolbar toolbar = findViewById(R.id.toolbar); + setSupportActionBar(toolbar); + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + getSupportActionBar().setDisplayShowHomeEnabled(true); + mAuth = FirebaseAuth.getInstance(); + mCurrentUser = mAuth.getCurrentUser(); + newUser = FirebaseDatabase.getInstance().getReference().child(mCurrentUser.getUid()); + newUser.child("email").setValue(mCurrentUser.getEmail()); + String name = mCurrentUser.getDisplayName(); + String email = mCurrentUser.getEmail(); + Uri picture = mCurrentUser.getPhotoUrl(); + profilePic = findViewById(R.id.profilePic); + profileUsername = findViewById(R.id.profileName); + saveBtn = findViewById(R.id.saveBtn); + loadingPb = findViewById(R.id.loadingPb); + //Glide.with(activity).load(picture).error(R.drawable.person_24).into(profilePic); + profileUsername.setText(name); + if (profileUsername.getText().toString().equals(mCurrentUser.getDisplayName())) { + saveBtn.setEnabled(false); + } else { + saveBtn.setEnabled(true); + } + TextWatcher afterTextChangedListener = new TextWatcher() { + @Override + public void beforeTextChanged(CharSequence s, int start, int count, int after) { + // ignore + } + + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) { + // ignore + } + + @Override + public void afterTextChanged(Editable s) { + if (profileUsername.getText().toString().trim().length() > 0) { + if (profileUsername.getText().toString().equals(mCurrentUser.getDisplayName())) { + saveBtn.setEnabled(false); + } else { + saveBtn.setEnabled(true); + } + } else { + saveBtn.setEnabled(false); + profileUsername.setError("username can't be empty!"); + } + } + }; + profilePic.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + Intent i = new Intent(Intent.ACTION_PICK); + i.setType("image/*"); + startActivityForResult(i, 1009); + } + }); + profileUsername.addTextChangedListener(afterTextChangedListener); + saveBtn.setOnClickListener(new View.OnClickListener() { + public void onClick(View view) { + loadingPb.setVisibility(View.VISIBLE); + + UserProfileChangeRequest profileUpdates = new UserProfileChangeRequest.Builder() + .setDisplayName(String.valueOf(profileUsername.getText())) + .setPhotoUri(imgUri) + .build(); + + mCurrentUser.updateProfile(profileUpdates) + .addOnCompleteListener(new OnCompleteListener() { + @Override + public void onComplete(@NonNull Task task) { + if (task.isSuccessful()) { + mCurrentUser.sendEmailVerification() + .addOnCompleteListener(new OnCompleteListener() { + @Override + public void onComplete(@NonNull Task task) { + saveBtn.setEnabled(false); + loadingPb.setVisibility(View.GONE); + View rootView = findViewById(R.id.main_layout); + Snackbar.make(rootView, "Updated Successfully!", 3000).show(); + } + }); + + } + } + }); + + } + }); + + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (requestCode == 1009 && resultCode == RESULT_OK) { + imgUri = data.getData(); + Glide.with(activity).load(imgUri).into(profilePic); + saveBtn.setEnabled(true); + } + } + + @Override + public boolean onOptionsItemSelected(@NonNull MenuItem item) { + if (item.getItemId() == android.R.id.home) { + finish(); + } + return super.onOptionsItemSelected(item); + } + + public void onBackPressed() { + finish(); + super.onBackPressed(); + } + + @Override + public void onResume() { + super.onResume(); + if (profileUsername.getText().toString().equals(mCurrentUser.getDisplayName())) { + saveBtn.setEnabled(false); + } else { + saveBtn.setEnabled(true); + } + } + + @Override + public void onPause() { + super.onPause(); + if (profileUsername.getText().toString().equals(mCurrentUser.getDisplayName())) { + saveBtn.setEnabled(false); + } else { + saveBtn.setEnabled(true); + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/vectras/vm/Roms/AdapterRoms.java b/app/src/main/java/com/vectras/vm/Roms/AdapterRoms.java new file mode 100644 index 0000000..854ae2d --- /dev/null +++ b/app/src/main/java/com/vectras/vm/Roms/AdapterRoms.java @@ -0,0 +1,128 @@ +package com.vectras.vm.Roms; + +import android.content.Context; +import android.content.Intent; +import android.net.Uri; +import android.graphics.Color; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.view.animation.Animation; +import android.view.animation.AnimationUtils; +import android.webkit.URLUtil; +import android.widget.ImageButton; +import android.widget.ImageView; +import android.widget.RadioButton; +import android.widget.TextView; + +import androidx.appcompat.app.AlertDialog; +import androidx.cardview.widget.CardView; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.vectras.vm.AppConfig; +import com.bumptech.glide.Glide; +import com.vectras.vm.RomsManagerActivity; +import com.vectras.vm.MainActivity; +import com.vectras.vm.R; +import com.vectras.vm.utils.FileUtils; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Locale; + +import androidx.appcompat.app.AlertDialog; + +import android.content.DialogInterface; +import android.app.Dialog; + +public class AdapterRoms extends RecyclerView.Adapter { + + private Context context; + private LayoutInflater inflater; + static List data = Collections.emptyList(); + static List filteredData = Collections.emptyList(); + DataRoms current; + int currentPos = 0; + private int mSelectedItem = -1; + + // create constructor to innitilize context and data sent from MainActivity + public AdapterRoms(Context context, List data) { + this.context = context; + inflater = LayoutInflater.from(context); + AdapterRoms.data = data; + AdapterRoms.filteredData = data; + } + + // Inflate the layout when viewholder created + @Override + public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { + View view = inflater.inflate(R.layout.container_roms, parent, false); + MyHolder holder = new MyHolder(view); + return holder; + } + + // Bind data + @Override + public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) { + + // Get current position of item in recyclerview to bind data and assign values from list + final MyHolder myHolder = (MyHolder) holder; + final DataRoms current = data.get(position); + Glide.with(RomsManagerActivity.activity).load(current.itemIcon).into(myHolder.ivIcon); + myHolder.textName.setText(current.itemName + " " + current.itemArch); + myHolder.textSize.setText(current.itemSize); + myHolder.checkBox.setChecked(position == mSelectedItem); + if (current.itemAvail) { + myHolder.textAvail.setText("availability: available"); + myHolder.textAvail.setTextColor(Color.GREEN); + } else if (!current.itemAvail) { + myHolder.textAvail.setText("availability: unavailable"); + myHolder.textAvail.setTextColor(Color.RED); + myHolder.checkBox.setEnabled(false); + } + if (current.itemAvail) + myHolder.checkBox.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + mSelectedItem = position; + notifyItemRangeChanged(0, data.size()); + RomsManagerActivity.selected = true; + RomsManagerActivity.selectedPath = current.itemPath; + RomsManagerActivity.selectedExtra = current.itemExtra; + RomsManagerActivity.selectedName = current.itemName + " " + current.itemArch; + RomsManagerActivity.selectedLink = current.itemUrl; + RomsManagerActivity.selectedIcon = current.itemIcon; + } + }); + + } + + // return total item from List + @Override + public int getItemCount() { + return data.size(); + } + + class MyHolder extends RecyclerView.ViewHolder { + + TextView textName, textAvail, textSize; + ImageView ivIcon; + + RadioButton checkBox; + + // create constructor to get widget reference + public MyHolder(View itemView) { + super(itemView); + textName = (TextView) itemView.findViewById(R.id.textName); + ivIcon = (ImageView) itemView.findViewById(R.id.ivIcon); + textSize = (TextView) itemView.findViewById(R.id.textSize); + textAvail = (TextView) itemView.findViewById(R.id.textAvail); + + checkBox = (RadioButton) itemView.findViewById(R.id.checkBox); + } + + } + +} diff --git a/app/src/main/java/com/vectras/vm/Roms/DataRoms.java b/app/src/main/java/com/vectras/vm/Roms/DataRoms.java new file mode 100644 index 0000000..e36c36e --- /dev/null +++ b/app/src/main/java/com/vectras/vm/Roms/DataRoms.java @@ -0,0 +1,14 @@ +package com.vectras.vm.Roms; + +public class DataRoms { + + public String itemIcon; + public String itemName; + public String itemArch; + public String itemKernel; + public Boolean itemAvail; + public String itemSize; + public String itemUrl; + public String itemPath; + public String itemExtra; +} diff --git a/app/src/main/java/com/vectras/vm/RomsManagerActivity.java b/app/src/main/java/com/vectras/vm/RomsManagerActivity.java new file mode 100644 index 0000000..044fa39 --- /dev/null +++ b/app/src/main/java/com/vectras/vm/RomsManagerActivity.java @@ -0,0 +1,646 @@ +package com.vectras.vm; + +import static android.content.Intent.ACTION_OPEN_DOCUMENT; + +import android.app.Activity; +import android.app.Dialog; +import android.app.ProgressDialog; +import android.content.Context; +import android.content.DialogInterface; +import android.content.Intent; +import android.content.SharedPreferences; +import android.content.res.Resources; +import android.database.Cursor; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.media.MediaScannerConnection; +import android.net.Uri; +import android.os.AsyncTask; +import android.os.Build; +import android.os.Bundle; +import android.os.Environment; +import android.provider.DocumentsContract; +import android.provider.MediaStore; +import android.text.Html; +import android.util.Log; +import android.view.MenuItem; +import android.view.View; +import android.webkit.URLUtil; +import android.widget.CheckBox; +import android.widget.CompoundButton; +import android.widget.Toast; + +import androidx.annotation.NonNull; +import androidx.appcompat.app.AlertDialog; +import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.widget.Toolbar; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.google.android.material.button.MaterialButtonToggleGroup; +import com.vectras.vm.AppConfig; +import com.vectras.vm.MainRoms.AdapterMainRoms; +import com.vectras.vm.MainRoms.DataMainRoms; +import com.vectras.vm.Roms.AdapterRoms; +import com.vectras.vm.Roms.DataRoms; +import com.vectras.vm.logger.VectrasStatus; +import com.vectras.qemu.utils.FileInstaller; +import com.vectras.vm.utils.FileUtils; + +import java.io.BufferedInputStream; + +import com.vectras.vm.utils.UIUtils; +import com.google.android.material.button.MaterialButton; + +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.FileDescriptor; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileWriter; +import java.io.InputStream; +import java.io.FileOutputStream; +import java.io.OutputStream; +import java.io.File; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.Writer; +import java.net.HttpURLConnection; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLConnection; +import java.nio.channels.FileChannel; +import java.util.ArrayList; +import java.util.List; +import java.util.Timer; +import java.util.TimerTask; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; + +import javax.net.ssl.HttpsURLConnection; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +public class RomsManagerActivity extends AppCompatActivity { + public static RomsManagerActivity activity; + + public static MaterialButton goBtn; + + public static CheckBox acceptLiceneseChkBox; + public static AlertDialog ad; + + public static String license; + public static RecyclerView mRVRoms; + public static AdapterRoms mAdapter; + public static String Data; + public static List data; + public static Boolean selected = false; + public static String selectedPath = null; + public static String selectedExtra = null; + public static String selectedLink = null; + public static String selectedName = null; + public static String selectedIcon = null; + + public MaterialButtonToggleGroup filterToggle; + public MaterialButton windowsToggle; + public MaterialButton linuxToggle; + public MaterialButton appleToggle; + public MaterialButton androidToggle; + public MaterialButton otherToggle; + + /** + * Called when the activity is first created. + */ + @Override + public void onCreate(Bundle savedInstanceState) { + + super.onCreate(savedInstanceState); + activity = this; + setContentView(R.layout.activity_roms_manager); + filterToggle = findViewById(R.id.filterToggle); + windowsToggle = findViewById(R.id.windowsToggle); + linuxToggle = findViewById(R.id.linuxToggle); + appleToggle = findViewById(R.id.appleToggle); + androidToggle = findViewById(R.id.androidToggle); + otherToggle = findViewById(R.id.otherToggle); + mRVRoms = findViewById(R.id.romsRv); + filterToggle.addOnButtonCheckedListener(new MaterialButtonToggleGroup.OnButtonCheckedListener() { + @Override + public void onButtonChecked(MaterialButtonToggleGroup group, int checkedId, boolean isChecked) { + if (checkedId == R.id.windowsToggle) { + if (isChecked) + filter = "windows"; + else + filter = null; + } else if (checkedId == R.id.linuxToggle) { + if (isChecked) + filter = "linux"; + else + filter = null; + } else if (checkedId == R.id.appleToggle) { + if (isChecked) + filter = "apple"; + else + filter = null; + } else if (checkedId == R.id.androidToggle) { + if (isChecked) + filter = "android"; + else + filter = null; + } else if (checkedId == R.id.otherToggle) { + if (isChecked) + filter = "other"; + else + filter = null; + } + new RomsManagerActivity.AsyncLogin().execute(); + } + }); + + Toolbar toolbar = findViewById(R.id.toolbar); + setSupportActionBar(toolbar); + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + getSupportActionBar().setDisplayShowHomeEnabled(true); + + new RomsManagerActivity.AsyncLogin().execute(); + new Thread(new Runnable() { + + public void run() { + + BufferedReader reader = null; + final StringBuilder builder = new StringBuilder(); + + try { + // Create a URL for the desired page + URL url = new URL(AppConfig.vectrasTerms); //My text file location + //First open the connection + HttpURLConnection conn = (HttpURLConnection) url.openConnection(); + conn.setConnectTimeout(60000); // timing out in a minute + + BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream())); + + //t=(TextView)findViewById(R.id.TextView1); // ideally do this in onCreate() + String str; + while ((str = in.readLine()) != null) { + builder.append(str); + } + in.close(); + } catch (Exception e) { + acceptLiceneseChkBox.setEnabled(false); + UIUtils.toastLong(activity, "no internet connection "+e.toString()); + } + + //since we are in background thread, to post results we have to go back to ui thread. do the following for that + + activity.runOnUiThread(new Runnable() { + public void run() { + license = builder.toString(); // My TextFile has 3 lines + acceptLiceneseChkBox.setEnabled(true); + } + }); + + } + }).start(); + + acceptLiceneseChkBox = findViewById(R.id.acceptLiceneseChkBox); + + acceptLiceneseChkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + + @Override + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + if (isChecked) { + UIAlertLicense("Terms&Conditions", license, activity); + } else { + goBtn.setEnabled(false); + } + } + }); + goBtn = (MaterialButton) findViewById(R.id.goBtn); + + goBtn.setOnClickListener(new View.OnClickListener() { + + @Override + public void onClick(View view) { + onFirstStartup(); + } + }); + + } + + public static void UIAlertLicense(String title, String html, final Activity activity) { + AlertDialog alertDialog; + alertDialog = new AlertDialog.Builder(activity, R.style.MainDialogTheme).create(); + alertDialog.setTitle(title); + alertDialog.setCancelable(true); + + alertDialog.setMessage(Html.fromHtml(html)); + + alertDialog.setButton(DialogInterface.BUTTON_POSITIVE, "I Acknowledge", new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int which) { + acceptLiceneseChkBox.setChecked(true); + goBtn.setEnabled(true); + return; + } + }); + alertDialog.setOnCancelListener(new DialogInterface.OnCancelListener() { + @Override + public void onCancel(DialogInterface dialog) { + acceptLiceneseChkBox.setChecked(false); + goBtn.setEnabled(false); + } + }); + alertDialog.show(); + } + + public static String filter = null; + + public static class AsyncLogin extends AsyncTask { + + @Override + protected void onPreExecute() { + super.onPreExecute(); + + //this method will be running on UI thread + + } + + @Override + protected String doInBackground(String... params) { + HttpsURLConnection con = null; + try { + URL u = new URL(AppConfig.romsJson); + con = (HttpsURLConnection) u.openConnection(); + + con.connect(); + + BufferedReader br = new BufferedReader(new InputStreamReader(con.getInputStream())); + StringBuilder sb = new StringBuilder(); + String line; + while ((line = br.readLine()) != null) { + sb.append(line + "\n"); + } + br.close(); + Data = sb.toString(); + + return (Data); + + } catch (MalformedURLException ex) { + ex.printStackTrace(); + } catch (IOException ex) { + ex.printStackTrace(); + } finally { + if (con != null) { + try { + con.disconnect(); + } catch (Exception ex) { + ex.printStackTrace(); + } + } + return ("unsuccessful!"); + } + + } + + @Override + protected void onPostExecute(String result) { + + //this method will be running on UI thread + data = new ArrayList<>(); + + try { + + JSONArray jArray = new JSONArray(Data); + + // Extract data from json and store into ArrayList as class objects + for (int i = 0; i < jArray.length(); i++) { + JSONObject json_data = jArray.getJSONObject(i); + DataRoms romsData = new DataRoms(); + romsData.itemName = json_data.getString("rom_name"); + romsData.itemIcon = json_data.getString("rom_icon"); + romsData.itemUrl = json_data.getString("rom_url"); + romsData.itemPath = json_data.getString("rom_path"); + romsData.itemAvail = json_data.getBoolean("rom_avail"); + romsData.itemSize = json_data.getString("rom_size"); + romsData.itemArch = json_data.getString("rom_arch"); + romsData.itemKernel = json_data.getString("rom_kernel"); + romsData.itemExtra = json_data.getString("rom_extra"); + if (filter != null) { + if (romsData.itemKernel.toLowerCase().contains(filter.toLowerCase())) { + data.add(romsData); + } + } else { + data.add(romsData); + } + } + + // Setup and Handover data to recyclerview + + } catch (JSONException e) { + UIUtils.toastLong(activity, e.toString()); + } + mRVRoms = (RecyclerView) activity.findViewById(R.id.romsRv); + mAdapter = new AdapterRoms(activity, data); + mRVRoms.setAdapter(mAdapter); + mRVRoms.setLayoutManager(new LinearLayoutManager(activity, LinearLayoutManager.VERTICAL, false)); + + } + + } + + @Override + public boolean onOptionsItemSelected(@NonNull MenuItem item) { + if (item.getItemId() == android.R.id.home) { + finish(); + } + return super.onOptionsItemSelected(item); + } + + public class RomsJso extends JSONObject { + + public JSONObject makeJSONObject(String imgName, String imgIcon, String imgPath, String imgExtra) { + + JSONObject obj = new JSONObject(); + + try { + obj.put("imgName", imgName); + obj.put("imgIcon", imgIcon); + obj.put("imgPath", imgPath); + obj.put("imgExtra", imgExtra); + } catch (JSONException e) { + e.printStackTrace(); + } + + return obj; + } + } + + public static final String CREDENTIAL_SHARED_PREF = "settings_prefs"; + + private void startIconDownload() { + new DownloadsImage().execute(selectedIcon); + } + + public void onFirstStartup() { + if (selected) { + if (FileUtils.fileValid(activity, AppConfig.maindirpath + selectedPath)) { + SharedPreferences credentials = activity.getSharedPreferences(CREDENTIAL_SHARED_PREF, Context.MODE_PRIVATE); + ProgressDialog mProgressDialog = new ProgressDialog(this, R.style.MainDialogTheme); + mProgressDialog.setTitle("Data Setup"); + mProgressDialog.setMessage("Please Wait..."); + mProgressDialog.setCancelable(false); + mProgressDialog.show(); + //FileInstaller.installFiles(activity, false); + SharedPreferences.Editor editor = credentials.edit(); + editor.putBoolean("isFirstLaunch", Boolean.TRUE); + editor.apply(); + RomsJso obj = new RomsJso(); + startIconDownload(); + final File jsonFile = new File(AppConfig.maindirpath + "roms-data" + ".json"); + + if (jsonFile.exists()) { + try { + List data = new ArrayList<>(); + JSONArray jArray = new JSONArray(FileUtils.readFromFile(MainActivity.activity, jsonFile)); + + try { + // Extract data from json and store into ArrayList as class objects + for (int i = 0; i < jArray.length(); i++) { + JSONObject json_data = jArray.getJSONObject(i); + DataMainRoms romsMainData = new DataMainRoms(); + romsMainData.itemName = json_data.getString("imgName"); + romsMainData.itemIcon = json_data.getString("imgIcon"); + romsMainData.itemPath = json_data.getString("imgPath"); + romsMainData.itemExtra = json_data.getString("imgExtra"); + data.add(romsMainData); + } + + } catch (JSONException e) { + Toast.makeText(MainActivity.activity, e.toString(), Toast.LENGTH_LONG).show(); + } + + JSONObject jsonObject = obj.makeJSONObject(selectedName, AppConfig.maindirpath + "icons/" + selectedPath.replace(".IMG", ".jpg"), AppConfig.maindirpath + selectedPath, selectedExtra); + jArray.put(jsonObject); + try { + Writer output = null; + output = new BufferedWriter(new FileWriter(jsonFile)); + output.write(jArray.toString().replace("\\", "").replace("//", "/")); + output.close(); + } catch (Exception e) { + UIUtils.toastLong(activity, e.toString()); + } + } catch (JSONException e) { + UIUtils.toastLong(activity, e.toString()); + } + } else { + JSONObject jsonObject = obj.makeJSONObject(selectedName, AppConfig.maindirpath + "icons/" + selectedPath.replace(".IMG", ".jpg"), AppConfig.maindirpath + selectedPath, selectedExtra); + JSONArray jsonArray = new JSONArray(); + jsonArray.put(jsonObject); + try { + Writer output = null; + output = new BufferedWriter(new FileWriter(jsonFile)); + output.write(jsonArray.toString().replace("\\", "").replace("//", "/")); + output.close(); + } catch (Exception e) { + UIUtils.toastLong(activity, e.toString()); + } + VectrasStatus.logInfo("Welcome to Vectras ♡"); + } + activity.startActivity(new Intent(activity, MainActivity.class)); + + /*new Timer().schedule(new TimerTask() { + @Override + public void run() { + mProgressDialog.dismiss(); } + }, 3000);*/ + } else { + AlertDialog ad; + ad = new AlertDialog.Builder(activity, R.style.MainDialogTheme).create(); + ad.setTitle(selectedPath.replace(".IMG", ".vbi") + " Needs to import"); + ad.setMessage("press import button and select " + selectedPath.replace(".IMG", ".vbi") + " file."); + ad.setButton(Dialog.BUTTON_POSITIVE, "IMPORT", (dialog, which) -> { + Intent intent = new Intent(ACTION_OPEN_DOCUMENT); + intent.addCategory(Intent.CATEGORY_OPENABLE); + intent.setType("*/*"); + + // Optionally, specify a URI for the file that should appear in the + // system file picker when it loads. + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + intent.putExtra(DocumentsContract.EXTRA_INITIAL_URI, Environment.DIRECTORY_DOWNLOADS); + } + + startActivityForResult(intent, 0); + }); + ad.setButton(Dialog.BUTTON_NEGATIVE, "DOWNLAOD " + selectedPath.replace(".IMG", ".vbi"), new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int which) { + String gt = selectedLink; + Intent g = new Intent(Intent.ACTION_VIEW); + g.setData(Uri.parse(gt)); + RomsManagerActivity.activity.startActivity(g); + RomsManagerActivity.activity.finish(); + } + }); + ad.show(); + } + } else { + AlertDialog ad; + ad = new AlertDialog.Builder(activity, R.style.MainDialogTheme).create(); + ad.setTitle("Please Select"); + ad.setMessage("Select the os (operating system) you need."); + ad.setButton(Dialog.BUTTON_POSITIVE, "OK", new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int which) { + return; + } + }); + ad.show(); + } + } + + public String getPath(Uri uri) { + return FileUtils.getPath(activity, uri); + } + + public ProgressDialog progressDialog = null; + + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (requestCode == 0 && resultCode == RESULT_OK) { + Uri content_describer = data.getData(); + File selectedFilePath = new File(getPath(content_describer)); + if (selectedFilePath.getName().equals(selectedPath.replace(".IMG", ".vbi"))) { + + try { + progressDialog = new ProgressDialog(activity, + R.style.MainDialogTheme); + progressDialog.setTitle("Extracting"); + progressDialog.setMessage("Please wait..."); + progressDialog.setCancelable(false); + progressDialog.show(); // Showing Progress Dialog + Thread t = new Thread() { + public void run() { + FileInputStream zipFile = null; + try { + zipFile = (FileInputStream) getContentResolver().openInputStream(content_describer); + } catch (FileNotFoundException e) { + throw new RuntimeException(e); + } + File targetDirectory = new File(AppConfig.maindirpath); + ZipInputStream zis = null; + zis = new ZipInputStream( + new BufferedInputStream(zipFile)); + try { + ZipEntry ze; + int count; + byte[] buffer = new byte[8192]; + while ((ze = zis.getNextEntry()) != null) { + File file = new File(targetDirectory, ze.getName()); + File dir = ze.isDirectory() ? file : file.getParentFile(); + if (!dir.isDirectory() && !dir.mkdirs()) + throw new FileNotFoundException("Failed to ensure directory: " + + dir.getAbsolutePath()); + if (ze.isDirectory()) + continue; + try (FileOutputStream fout = new FileOutputStream(file)) { + while ((count = zis.read(buffer)) != -1) + fout.write(buffer, 0, count); + } + /* if time should be restored as well + long time = ze.getTime(); + if (time > 0) + file.setLastModified(time); + */ + } + } catch (IOException e) { + UIUtils.toastLong(activity, e.toString()); + throw new RuntimeException(e); + } finally { + progressDialog.cancel(); // cancelling Dialog. + try { + zis.close(); + } catch (IOException e) { + UIUtils.toastLong(activity, e.toString()); + throw new RuntimeException(e); + } + } + } + }; + t.start(); + } catch (Exception e) { + progressDialog.dismiss(); // Close Progress Dialog + UIUtils.toastLong(activity, e.toString()); + throw new RuntimeException(e); + } + + } else { + MainActivity.UIAlert("File not supported", "please select " + selectedPath.replace(".IMG", ".vbi") + " file to continue.", activity); + } + + } + } + + public static final int DIALOG_DOWNLOAD_PROGRESS = 0; + + static class DownloadsImage extends AsyncTask { + + @Override + protected Void doInBackground(String... strings) { + URL url = null; + try { + url = new URL(strings[0]); + } catch (MalformedURLException e) { + e.printStackTrace(); + } + Bitmap bm = null; + try { + bm = BitmapFactory.decodeStream(url.openConnection().getInputStream()); + } catch (IOException e) { + e.printStackTrace(); + } + + //Create Path to save Image + File path = new File(AppConfig.maindirpath + "icons"); //Creates app specific folder + + if (!path.exists()) { + path.mkdirs(); + } + + File imageFile = new File(path, selectedPath.replace(".IMG", ".jpg")); // Imagename.png + FileOutputStream out = null; + try { + out = new FileOutputStream(imageFile); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } + try { + bm.compress(Bitmap.CompressFormat.PNG, 100, out); // Compress Image + out.flush(); + out.close(); + // Tell the media scanner about the new file so that it is + // immediately available to the user. + MediaScannerConnection.scanFile(activity, new String[]{imageFile.getAbsolutePath()}, null, new MediaScannerConnection.OnScanCompletedListener() { + public void onScanCompleted(String path, Uri uri) { + // Log.i("ExternalStorage", "Scanned " + path + ":"); + // Log.i("ExternalStorage", "-> uri=" + uri); + } + }); + } catch (Exception ignored) { + } + return null; + } + + @Override + protected void onPostExecute(Void aVoid) { + super.onPostExecute(aVoid); + } + } + + @Override + public void onBackPressed() { + super.onBackPressed(); + if (getParentActivityIntent() == MainActivity.activity.getIntent()) + finish(); + } + +} diff --git a/app/src/main/java/com/vectras/vm/SplashActivity.java b/app/src/main/java/com/vectras/vm/SplashActivity.java new file mode 100644 index 0000000..dfa9f54 --- /dev/null +++ b/app/src/main/java/com/vectras/vm/SplashActivity.java @@ -0,0 +1,85 @@ +package com.vectras.vm; + +import static android.os.Build.VERSION.SDK_INT; + +import android.Manifest; +import android.animation.ValueAnimator; +import android.app.ActivityManager; +import android.app.Dialog; +import android.content.*; +import android.content.pm.*; +import android.net.Uri; +import android.os.*; +import android.preference.PreferenceManager; +import android.provider.Settings; +import android.view.*; +import android.graphics.*; + +import androidx.appcompat.app.AlertDialog; +import androidx.appcompat.app.AppCompatActivity; +import androidx.core.app.ActivityCompat; +import androidx.core.content.ContextCompat; + +import com.airbnb.lottie.LottieAnimationView; +import com.google.firebase.auth.FirebaseAuth; +import com.vectras.qemu.MainActivityCommon; +import com.vectras.qemu.MainSettingsManager; +import com.vectras.qemu.utils.RamInfo; +import com.vectras.vm.R; +import com.vectras.vm.MainActivity; +import com.vectras.vm.ui.login.LoginActivity; +import com.vectras.vm.utils.UIUtils; + +import java.io.File; + +public class SplashActivity extends AppCompatActivity implements Runnable { + public AlertDialog ad; + public static SplashActivity activity; + private FirebaseAuth mAuth; + + @Override + protected void onCreate(Bundle bundle) { + super.onCreate(bundle); + activity = this; + File baseDir = new File(AppConfig.basefiledir); + if (!baseDir.exists()) { + baseDir.mkdirs(); + } + setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED); + requestWindowFeature(Window.FEATURE_NO_TITLE); + setContentView(R.layout.activity_splash); + + new Handler().postDelayed(this, 3000); + File sharedDir = new File(AppConfig.sharedFolder); + if (!sharedDir.exists()) { + sharedDir.mkdirs(); + } + File mainDir = new File(AppConfig.maindirpath); + if (!mainDir.exists()) { + mainDir.mkdirs(); + } + // Initialize Firebase Auth + mAuth = FirebaseAuth.getInstance(); + RamInfo.activity = activity; + + MainSettingsManager.setOrientationSetting(activity, 1); + } + + public static final String CREDENTIAL_SHARED_PREF = "settings_prefs"; + + @Override + public void run() { + SharedPreferences prefs = getSharedPreferences(CREDENTIAL_SHARED_PREF, Context.MODE_PRIVATE); + + boolean isAccessed = prefs.getBoolean("isFirstLaunch", false); + if (!isAccessed) { + startActivity(new Intent(this, LoginActivity.class)); + } else { + if (FirebaseAuth.getInstance().getCurrentUser() != null) + startActivity(new Intent(this, MainActivity.class)); + else + startActivity(new Intent(this, LoginActivity.class)); + } + finish(); + } +} diff --git a/app/src/main/java/com/vectras/vm/Store/AdapterStore.java b/app/src/main/java/com/vectras/vm/Store/AdapterStore.java new file mode 100644 index 0000000..a75707d --- /dev/null +++ b/app/src/main/java/com/vectras/vm/Store/AdapterStore.java @@ -0,0 +1,103 @@ +package com.vectras.vm.Store; + +import android.content.Context; +import android.content.Intent; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.view.animation.Animation; +import android.view.animation.AnimationUtils; +import android.widget.ImageView; +import android.widget.TextView; +import androidx.cardview.widget.CardView; +import androidx.fragment.app.FragmentTransaction; +import androidx.recyclerview.widget.RecyclerView; +import com.bumptech.glide.Glide; +import com.vectras.vm.R; +import com.vectras.vm.Fragment.HomeFragment; +import com.vectras.vm.PostActivity; +import java.util.Collections; +import java.util.List; +import com.vectras.vm.MainActivity; +import com.vectras.vm.StoreActivity; +import com.vectras.vm.StoreItemActivity; + +public class AdapterStore extends RecyclerView.Adapter { + + private Context context; + private LayoutInflater inflater; + List data = Collections.emptyList(); + DataStore current; + int currentPos = 0; + + // create constructor to innitilize context and data sent from MainActivity + public AdapterStore(Context context, List data) { + this.context = context; + inflater = LayoutInflater.from(context); + this.data = data; + } + + // Inflate the layout when viewholder created + @Override + public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { + View view = inflater.inflate(R.layout.container_store, parent, false); + MyHolder holder = new MyHolder(view); + return holder; + } + + // Bind data + @Override + public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { + + // Get current position of item in recyclerview to bind data and assign values from list + MyHolder myHolder = (MyHolder) holder; + final DataStore current = data.get(position); + myHolder.textName.setText(current.itemName); + myHolder.textSize.setText("Size: " + current.itemSize); + Glide.with(StoreActivity.activity).load(current.itemIcon).into(myHolder.ivIcon); + Animation animation; + animation = AnimationUtils.loadAnimation(MainActivity.activity, android.R.anim.slide_in_left); + animation.setDuration(300); + + myHolder.cdItem.startAnimation(animation); + animation = null; + myHolder.cdItem.setOnClickListener(new View.OnClickListener() { + public void onClick(View view) { + StoreItemActivity.name = current.itemName; + StoreItemActivity.icon = current.itemIcon; + StoreItemActivity.size = current.itemSize; + StoreItemActivity.desc = current.itemData; + StoreItemActivity.link = current.itemLink; + StoreItemActivity.prvMain = current.itemPreviewMain; + StoreItemActivity.prv1 = current.itemPreview1; + StoreItemActivity.prv2 = current.itemPreview2; + StoreActivity.activity.startActivity(new Intent(StoreActivity.activity, StoreItemActivity.class)); + } + }); + } + + // return total item from List + @Override + public int getItemCount() { + return data.size(); + } + + class MyHolder extends RecyclerView.ViewHolder { + + CardView cdItem; + TextView textName; + ImageView ivIcon; + TextView textSize; + + // create constructor to get widget reference + public MyHolder(View itemView) { + super(itemView); + cdItem = (CardView) itemView.findViewById(R.id.cdItem); + textName = (TextView) itemView.findViewById(R.id.textName); + ivIcon = (ImageView) itemView.findViewById(R.id.ivIcon); + textSize = (TextView) itemView.findViewById(R.id.textSize); + } + + } + +} diff --git a/app/src/main/java/com/vectras/vm/Store/DataStore.java b/app/src/main/java/com/vectras/vm/Store/DataStore.java new file mode 100644 index 0000000..3e623f2 --- /dev/null +++ b/app/src/main/java/com/vectras/vm/Store/DataStore.java @@ -0,0 +1,13 @@ +package com.vectras.vm.Store; + +public class DataStore { + + public String itemName; + public String itemSize; + public String itemData; + public String itemIcon; + public String itemLink; + public String itemPreviewMain; + public String itemPreview1; + public String itemPreview2; +} diff --git a/app/src/main/java/com/vectras/vm/StoreActivity.java b/app/src/main/java/com/vectras/vm/StoreActivity.java new file mode 100644 index 0000000..02cd874 --- /dev/null +++ b/app/src/main/java/com/vectras/vm/StoreActivity.java @@ -0,0 +1,204 @@ +package com.vectras.vm; + +import android.content.Context; +import android.net.ConnectivityManager; +import android.net.NetworkInfo; +import android.os.*; +import android.view.MenuItem; +import android.view.View; +import android.widget.LinearLayout; +import android.widget.Toast; + +import androidx.annotation.NonNull; +import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.widget.Toolbar; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; +import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; + +import com.google.android.gms.ads.AdRequest; +import com.google.android.gms.ads.AdView; +import com.vectras.vm.R; +import com.vectras.vm.Blog.AdapterBlog; +import com.vectras.vm.Blog.DataBlog; +import com.vectras.vm.Fragment.HomeFragment; +import com.vectras.vm.Store.AdapterStore; +import com.vectras.vm.Store.DataStore; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.ArrayList; +import java.util.List; + +import javax.net.ssl.HttpsURLConnection; + +public class StoreActivity extends AppCompatActivity{ + private RecyclerView mRVStore; + private AdapterStore mAdapter; + public static LinearLayout noConnectionLayout; + public SwipeRefreshLayout pullToRefresh; + public static StoreActivity activity; + public String Data; + @Override + protected void onCreate(Bundle bundle) { + super.onCreate(bundle); + setContentView(R.layout.activity_store); + Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); + setSupportActionBar(toolbar); + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + getSupportActionBar().setDisplayShowHomeEnabled(true); + toolbar.setTitle(getString(R.string.app_name)); + + activity = this; + + AdView mAdView = findViewById(R.id.adView); + AdRequest adRequest = new AdRequest.Builder().build(); + mAdView.loadAd(adRequest); + noConnectionLayout = findViewById(R.id.noConnectionLayout); + mRVStore = findViewById(R.id.storeRv); + + if (checkConnection(activity)) { + new StoreActivity.AsyncLogin().execute(); + noConnectionLayout.setVisibility(View.GONE); + //mRVBlog.setVisibility(View.VISIBLE); + } else { + noConnectionLayout.setVisibility(View.VISIBLE); + //mRVBlog.setVisibility(View.GONE); + } + + pullToRefresh = findViewById(R.id.refreshLayout); + pullToRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { + @Override + public void onRefresh() { + if (checkConnection(activity)) { + new StoreActivity.AsyncLogin().execute(); + } else { + noConnectionLayout.setVisibility(View.VISIBLE); + pullToRefresh.setRefreshing(false); + } + } + }); + } + public boolean checkConnection(Context context) { + final ConnectivityManager connMgr = (ConnectivityManager) context + .getSystemService(Context.CONNECTIVITY_SERVICE); + + if (connMgr != null) { + NetworkInfo activeNetworkInfo = connMgr.getActiveNetworkInfo(); + + if (activeNetworkInfo != null) { // connected to the internet + // connected to the mobile provider's data plan + if (activeNetworkInfo.getType() == ConnectivityManager.TYPE_WIFI) { + // connected to wifi + return true; + } else + return activeNetworkInfo.getType() == ConnectivityManager.TYPE_MOBILE; + } + } + return false; + } + + private class AsyncLogin extends AsyncTask { + + @Override + protected void onPreExecute() { + super.onPreExecute(); + + //this method will be running on UI thread + + } + + @Override + protected String doInBackground(String... params) { + HttpsURLConnection con = null; + try { + URL u = new URL(AppConfig.storeJson); + con = (HttpsURLConnection) u.openConnection(); + + con.connect(); + + BufferedReader br = new BufferedReader(new InputStreamReader(con.getInputStream())); + StringBuilder sb = new StringBuilder(); + String line; + while ((line = br.readLine()) != null) { + sb.append(line + "\n"); + } + br.close(); + Data = sb.toString(); + + return (Data); + + } catch (MalformedURLException ex) { + ex.printStackTrace(); + } catch (IOException ex) { + ex.printStackTrace(); + } finally { + if (con != null) { + try { + con.disconnect(); + } catch (Exception ex) { + ex.printStackTrace(); + } + } + return ("unsuccessful!"); + } + + } + + @Override + protected void onPostExecute(String result) { + + //this method will be running on UI thread + pullToRefresh.setRefreshing(false); + + noConnectionLayout.setVisibility(View.GONE); + + List data = new ArrayList<>(); + + try { + + JSONArray jArray = new JSONArray(Data); + + // Extract data from json and store into ArrayList as class objects + for (int i = 0; i < jArray.length(); i++) { + JSONObject json_data = jArray.getJSONObject(i); + DataStore storeData = new DataStore(); + storeData.itemName = json_data.getString("item_name"); + storeData.itemIcon = json_data.getString("item_icon"); + storeData.itemData = json_data.getString("item_data"); + storeData.itemSize = json_data.getString("item_size"); + storeData.itemLink = json_data.getString("item_link"); + storeData.itemPreviewMain = json_data.getString("item_preview_main"); + storeData.itemPreview1 = json_data.getString("item_preview_1"); + storeData.itemPreview2 = json_data.getString("item_preview_2"); + data.add(storeData); + } + + // Setup and Handover data to recyclerview + + } catch (JSONException e) { + Toast.makeText(activity, e.toString(), Toast.LENGTH_LONG).show(); + } + mRVStore = (RecyclerView) findViewById(R.id.storeRv); + mAdapter = new AdapterStore(activity, data); + mRVStore.setAdapter(mAdapter); + mRVStore.setLayoutManager(new LinearLayoutManager(activity)); + + } + + } + @Override + public boolean onOptionsItemSelected(@NonNull MenuItem item) { + if(item.getItemId()== android.R.id.home){ + finish(); + } + return super.onOptionsItemSelected(item); + } +} diff --git a/app/src/main/java/com/vectras/vm/StoreItemActivity.java b/app/src/main/java/com/vectras/vm/StoreItemActivity.java new file mode 100644 index 0000000..215ecc4 --- /dev/null +++ b/app/src/main/java/com/vectras/vm/StoreItemActivity.java @@ -0,0 +1,304 @@ +package com.vectras.vm; + +import android.app.Dialog; +import android.app.IntentService; +import android.app.ProgressDialog; +import android.content.Context; +import android.content.DialogInterface; +import android.content.Intent; +import android.net.Uri; +import android.os.*; +import android.text.Html; +import android.util.Log; +import android.view.MenuItem; +import android.view.View; +import android.webkit.MimeTypeMap; +import android.webkit.URLUtil; +import android.widget.Button; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.ProgressBar; +import android.widget.TextView; +import android.os.PowerManager; +import androidx.appcompat.app.AlertDialog; +import com.bumptech.glide.Glide; +import com.google.android.gms.ads.AdRequest; +import com.google.android.gms.ads.AdView; +import com.google.android.gms.ads.LoadAdError; +import com.google.android.gms.ads.MobileAds; +import com.google.android.gms.ads.initialization.InitializationStatus; +import com.google.android.gms.ads.initialization.OnInitializationCompleteListener; +import com.google.android.gms.ads.interstitial.InterstitialAd; +import com.google.android.gms.ads.interstitial.InterstitialAdLoadCallback; +import com.vectras.vm.utils.FileUtils; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.FileOutputStream; +import java.net.HttpURLConnection; +import androidx.annotation.NonNull; +import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.widget.Toolbar; +import com.vectras.vm.R; +import com.vectras.vm.utils.UIUtils; +import java.io.BufferedInputStream; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.net.HttpURLConnection; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLConnection; +import android.os.PowerManager; + +public class StoreItemActivity extends AppCompatActivity { + public StoreItemActivity activity; + public String TAG = "StoreItemActivity"; + public static String icon, name, size, desc, descStr, prvMain, prv1, prv2, link; + public TextView itemName, itemSize, itemDesc; + public Button dBtn; + public ImageView itemIcon, itemPrvMain, itemPrv1, itemPrv2; + + private InterstitialAd mInterstitialAd; + + @Override + protected void onCreate(Bundle bundle) { + activity = this; + super.onCreate(bundle); + setContentView(R.layout.activity_store_item); + Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); + setSupportActionBar(toolbar); + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + getSupportActionBar().setDisplayShowHomeEnabled(true); + toolbar.setTitle(getString(R.string.app_name)); + itemIcon = findViewById(R.id.ivIcon); + itemName = findViewById(R.id.textName); + itemSize = findViewById(R.id.textSize); + dBtn = findViewById(R.id.btn_download); + itemDesc = findViewById(R.id.descTxt); + itemPrvMain = findViewById(R.id.ivPrvMain); + itemPrv1 = findViewById(R.id.ivPrv1); + itemPrv2 = findViewById(R.id.ivPrv2); + + AdView mAdView = findViewById(R.id.adView); + AdRequest adRequest = new AdRequest.Builder().build(); + mAdView.loadAd(adRequest); + + MobileAds.initialize(this, new OnInitializationCompleteListener() { + @Override + public void onInitializationComplete(InitializationStatus initializationStatus) {} + }); + InterstitialAd.load(this,"ca-app-pub-3568137780412047/4892595373", adRequest, + new InterstitialAdLoadCallback() { + @Override + public void onAdLoaded(@NonNull InterstitialAd interstitialAd) { + // The mInterstitialAd reference will be null until + // an ad is loaded. + mInterstitialAd = interstitialAd; + Log.i(TAG, "onAdLoaded"); + } + + @Override + public void onAdFailedToLoad(@NonNull LoadAdError loadAdError) { + // Handle the error + Log.d(TAG, loadAdError.toString()); + mInterstitialAd = null; + } + }); + if (mInterstitialAd != null) { + mInterstitialAd.show(StoreItemActivity.this); + } else { + Log.d("TAG", "The interstitial ad wasn't ready yet."); + } + dBtn.setOnClickListener(new View.OnClickListener() { + + @Override + public void onClick(View view) { + + InterstitialAd.load(activity,"ca-app-pub-3568137780412047/7937545204", adRequest, + new InterstitialAdLoadCallback() { + @Override + public void onAdLoaded(@NonNull InterstitialAd interstitialAd) { + // The mInterstitialAd reference will be null until + // an ad is loaded. + mInterstitialAd = interstitialAd; + Log.i(TAG, "onAdLoaded"); + } + + @Override + public void onAdFailedToLoad(@NonNull LoadAdError loadAdError) { + // Handle the error + Log.d(TAG, loadAdError.toString()); + mInterstitialAd = null; + } + }); + startDownload(); + } + }); + itemName.setText(name); + itemSize.setText(size); + + Glide.with(this).load(icon).into(itemIcon); + Glide.with(this).load(prvMain).into(itemPrvMain); + Glide.with(this).load(prv1).into(itemPrv1); + Glide.with(this).load(prv2).into(itemPrv2); + new Thread(new Runnable() { + + public void run() { + + BufferedReader reader = null; + final StringBuilder builder = new StringBuilder(); + + try { + // Create a URL for the desired page + URL url = new URL(desc); //My text file location + //First open the connection + HttpURLConnection conn = (HttpURLConnection) url.openConnection(); + conn.setConnectTimeout(60000); // timing out in a minute + + BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream())); + + //t=(TextView)findViewById(R.id.TextView1); // ideally do this in onCreate() + String str; + while ((str = in.readLine()) != null) { + builder.append(str); + } + in.close(); + } catch (Exception e) { + itemDesc.setText("no internet connection"); + UIUtils.toastLong(StoreItemActivity.this, "check your internet connection"); + Log.d("VECTRAS", e.toString()); + } + + //since we are in background thread, to post results we have to go back to ui thread. do the following for that + + StoreItemActivity.this.runOnUiThread(new Runnable() { + public void run() { + descStr = builder.toString(); // My TextFile has 3 lines + itemDesc.setText(Html.fromHtml(descStr)); + } + }); + + } + }).start(); + itemPrvMain.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + ImagePrvActivity.linkIv = prvMain; + startActivity(new Intent(activity, ImagePrvActivity.class)); + } + }); + itemPrv1.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + ImagePrvActivity.linkIv = prv1; + startActivity(new Intent(activity, ImagePrvActivity.class)); + } + }); + itemPrv2.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + ImagePrvActivity.linkIv = prv2; + startActivity(new Intent(activity, ImagePrvActivity.class)); + } + }); + } + + public static final int DIALOG_DOWNLOAD_PROGRESS = 0; + private ProgressDialog mProgressDialog; + + private void startDownload() { + String url = link; + new DownloadFileAsync().execute(url); + } + + @Override + protected Dialog onCreateDialog(int id) { + switch (id) { + case DIALOG_DOWNLOAD_PROGRESS: + mProgressDialog = new ProgressDialog(this, R.style.MainDialogTheme); + mProgressDialog.setMessage("Downloading file.."); + mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); + mProgressDialog.setCancelable(false); + mProgressDialog.show(); + return mProgressDialog; + default: + return null; + } + } + + class DownloadFileAsync extends AsyncTask { + + @Override + protected void onPreExecute() { + super.onPreExecute(); + showDialog(DIALOG_DOWNLOAD_PROGRESS); + } + + @Override + protected String doInBackground(String... aurl) { + int count; + + try { + URL url = new URL(aurl[0]); + URLConnection conexion = url.openConnection(); + conexion.connect(); + + int lenghtOfFile = conexion.getContentLength(); + Log.d(TAG, "Lenght of file: " + lenghtOfFile); + String fileName = URLUtil.guessFileName(link,null,null); + InputStream input = new BufferedInputStream(url.openStream()); + OutputStream output = new FileOutputStream(AppConfig.sharedFolder+fileName); + + byte data[] = new byte[1024]; + + long total = 0; + + while ((count = input.read(data)) != -1) { + total += count; + publishProgress("" + (int) ((total * 100) / lenghtOfFile)); + output.write(data, 0, count); + } + + output.flush(); + output.close(); + input.close(); + } catch (Exception e) { + } + return null; + + } + + protected void onProgressUpdate(String... progress) { + Log.d(TAG, progress[0]); + mProgressDialog.setProgress(Integer.parseInt(progress[0])); + } + + @Override + protected void onPostExecute(String unused) { + dismissDialog(DIALOG_DOWNLOAD_PROGRESS); + AlertDialog ad; + ad = new AlertDialog.Builder(activity, R.style.MainDialogTheme).create(); + ad.setTitle("Downloaded Successfully!"); + String fileName = URLUtil.guessFileName(link,null,null); + ad.setMessage("Downloaded to path: "+AppConfig.sharedFolder+fileName+" boot vectras to check your downloads in QEMU VFAT partition."); + ad.setButton(Dialog.BUTTON_POSITIVE, "OK", new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int which) { + return; + } + }); + ad.show(); + } + } + + @Override + public boolean onOptionsItemSelected(@NonNull MenuItem item) { + if (item.getItemId() == android.R.id.home) { + finish(); + } + return super.onOptionsItemSelected(item); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/vectras/vm/VectrasApp.java b/app/src/main/java/com/vectras/vm/VectrasApp.java new file mode 100644 index 0000000..8ce9a98 --- /dev/null +++ b/app/src/main/java/com/vectras/vm/VectrasApp.java @@ -0,0 +1,379 @@ +package com.vectras.vm; + +import static android.view.WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS; + +import android.app.Activity; +import android.app.Application; +import android.content.ClipData; +import android.content.ClipboardManager; +import android.content.Context; +import android.content.Intent; +import android.content.pm.PackageInfo; +import android.content.res.Resources; +import android.graphics.Typeface; +import android.os.Build; +import android.os.Bundle; +import android.os.Handler; +import android.os.Looper; +import android.text.TextUtils; +import android.util.Log; +import android.view.Menu; +import android.view.MenuItem; +import android.view.ViewGroup; +import android.widget.HorizontalScrollView; +import android.widget.ScrollView; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.appcompat.app.AppCompatDelegate; + +import com.google.android.material.color.DynamicColors; +import com.vectras.qemu.MainSettingsManager; +import com.vectras.vm.logger.VectrasStatus; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.Closeable; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.lang.Thread.UncaughtExceptionHandler; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Arrays; +import java.util.Date; +import java.util.LinkedHashMap; +import java.util.concurrent.atomic.AtomicBoolean; + +public class VectrasApp extends Application { + + private static Handler MAIN_HANDLER = new Handler(Looper.getMainLooper()); + private static Context app; + + @Override + public void onCreate() { + super.onCreate(); + CrashHandler.getInstance().registerGlobal(this); + CrashHandler.getInstance().registerPart(this); + try { + Class.forName("android.os.AsyncTask"); + } catch (Throwable ignore) { + // ignored + } + app = getApplicationContext(); + setModeNight(this); + DynamicColors.applyToActivitiesIfAvailable(this); + } + + private void setModeNight(Context context) { + if (MainSettingsManager.getModeNight(context)) { + AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES); + setTheme(R.style.AppTheme); + } else { + AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO); + setTheme(R.style.AppTheme); + } + + } + + public static Context getApp() { + return app; + } + + public static void write(InputStream input, OutputStream output) throws IOException { + byte[] buf = new byte[1024 * 8]; + int len; + while ((len = input.read(buf)) != -1) { + output.write(buf, 0, len); + } + } + + public static void write(File file, byte[] data) throws IOException { + File parent = file.getParentFile(); + if (parent != null && !parent.exists()) + parent.mkdirs(); + + ByteArrayInputStream input = new ByteArrayInputStream(data); + FileOutputStream output = new FileOutputStream(file); + try { + write(input, output); + } finally { + closeIO(input, output); + } + } + + public static String toString(InputStream input) throws IOException { + ByteArrayOutputStream output = new ByteArrayOutputStream(); + write(input, output); + try { + return output.toString("UTF-8"); + } finally { + closeIO(input, output); + } + } + + public static void closeIO(Closeable... closeables) { + for (Closeable closeable : closeables) { + try { + if (closeable != null) + closeable.close(); + } catch (IOException ignored) { + } + } + } + + public static class CrashHandler { + + public static final UncaughtExceptionHandler DEFAULT_UNCAUGHT_EXCEPTION_HANDLER = Thread + .getDefaultUncaughtExceptionHandler(); + + private static CrashHandler sInstance; + + private PartCrashHandler mPartCrashHandler; + + public static CrashHandler getInstance() { + if (sInstance == null) { + sInstance = new CrashHandler(); + } + return sInstance; + } + + public void registerGlobal(Context context) { + registerGlobal(context, null); + } + + public void registerGlobal(Context context, String crashDir) { + Thread.setDefaultUncaughtExceptionHandler( + new UncaughtExceptionHandlerImpl(context.getApplicationContext(), crashDir)); + } + + public void unregister() { + Thread.setDefaultUncaughtExceptionHandler(DEFAULT_UNCAUGHT_EXCEPTION_HANDLER); + } + + public void registerPart(Context context) { + unregisterPart(context); + mPartCrashHandler = new PartCrashHandler(context.getApplicationContext()); + MAIN_HANDLER.postAtFrontOfQueue(mPartCrashHandler); + } + + public void unregisterPart(Context context) { + if (mPartCrashHandler != null) { + mPartCrashHandler.isRunning.set(false); + mPartCrashHandler = null; + } + } + + private static class PartCrashHandler implements Runnable { + + private final Context mContext; + + public AtomicBoolean isRunning = new AtomicBoolean(true); + + public PartCrashHandler(Context context) { + this.mContext = context; + } + + @Override + public void run() { + while (isRunning.get()) { + try { + Looper.loop(); + } catch (final Throwable e) { + e.printStackTrace(); + if (isRunning.get()) { + MAIN_HANDLER.post(new Runnable() { + + @Override + public void run() { + VectrasStatus.logError("[E] "+e.getMessage()+""); + } + }); + } else { + if (e instanceof RuntimeException) { + throw (RuntimeException) e; + } else { + throw new RuntimeException(e); + } + } + } + } + } + } + + private static class UncaughtExceptionHandlerImpl implements UncaughtExceptionHandler { + + private static DateFormat DATE_FORMAT = new SimpleDateFormat("yyyy_MM_dd-HH_mm_ss"); + + private final Context mContext; + + private final File mCrashDir; + + public UncaughtExceptionHandlerImpl(Context context, String crashDir) { + this.mContext = context; + this.mCrashDir = TextUtils.isEmpty(crashDir) ? new File(mContext.getExternalCacheDir(), "crash") + : new File(crashDir); + } + + @Override + public void uncaughtException(Thread thread, Throwable throwable) { + try { + + String log = buildLog(throwable); + writeLog(log); + + try { + Intent intent = new Intent(mContext, CrashActivity.class); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + intent.putExtra(Intent.EXTRA_TEXT, log); + mContext.startActivity(intent); + } catch (Throwable e) { + e.printStackTrace(); + writeLog(e.toString()); + } + + throwable.printStackTrace(); + android.os.Process.killProcess(android.os.Process.myPid()); + System.exit(0); + + } catch (Throwable e) { + if (DEFAULT_UNCAUGHT_EXCEPTION_HANDLER != null) + DEFAULT_UNCAUGHT_EXCEPTION_HANDLER.uncaughtException(thread, throwable); + } + } + + private String buildLog(Throwable throwable) { + String time = DATE_FORMAT.format(new Date()); + + String versionName = "unknown"; + long versionCode = 0; + try { + PackageInfo packageInfo = mContext.getPackageManager().getPackageInfo(mContext.getPackageName(), 0); + versionName = packageInfo.versionName; + versionCode = Build.VERSION.SDK_INT >= 28 ? packageInfo.getLongVersionCode() + : packageInfo.versionCode; + } catch (Throwable ignored) { + } + + LinkedHashMap head = new LinkedHashMap(); + head.put("Time Of Crash", time); + head.put("Device", String.format("%s, %s", Build.MANUFACTURER, Build.MODEL)); + head.put("Android Version", String.format("%s (%d)", Build.VERSION.RELEASE, Build.VERSION.SDK_INT)); + head.put("App Version", String.format("%s (%d)", versionName, versionCode)); + head.put("Kernel", getKernel()); + head.put("Support Abis", + Build.VERSION.SDK_INT >= 21 && Build.SUPPORTED_ABIS != null + ? Arrays.toString(Build.SUPPORTED_ABIS) + : "unknown"); + head.put("Fingerprint", Build.FINGERPRINT); + + StringBuilder builder = new StringBuilder(); + + for (String key : head.keySet()) { + if (builder.length() != 0) + builder.append("\n"); + builder.append(key); + builder.append(" : "); + builder.append(head.get(key)); + } + + builder.append("\n\n"); + builder.append(Log.getStackTraceString(throwable)); + + return builder.toString(); + } + + private void writeLog(String log) { + String time = DATE_FORMAT.format(new Date()); + File file = new File(mCrashDir, "crash_" + time + ".txt"); + try { + write(file, log.getBytes("UTF-8")); + } catch (Throwable e) { + e.printStackTrace(); + } + } + + private static String getKernel() { + try { + return VectrasApp.toString(new FileInputStream("/proc/version")).trim(); + } catch (Throwable e) { + return e.getMessage(); + } + } + } + } + + public static final class CrashActivity extends Activity { + + private String mLog; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + setTheme(android.R.style.Theme_DeviceDefault); + setTitle("App Crash"); + + mLog = getIntent().getStringExtra(Intent.EXTRA_TEXT); + + ScrollView contentView = new ScrollView(this); + contentView.setFillViewport(true); + + HorizontalScrollView horizontalScrollView = new HorizontalScrollView(this); + + TextView textView = new TextView(this); + int padding = dp2px(16); + textView.setPadding(padding, padding, padding, padding); + textView.setText(mLog); + textView.setTextIsSelectable(true); + textView.setTypeface(Typeface.DEFAULT); + textView.setLinksClickable(true); + + horizontalScrollView.addView(textView); + contentView.addView(horizontalScrollView, ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.MATCH_PARENT); + + setContentView(contentView); + } + + private void restart() { + Intent intent = getPackageManager().getLaunchIntentForPackage(getPackageName()); + if (intent != null) { + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + startActivity(intent); + } + finish(); + android.os.Process.killProcess(android.os.Process.myPid()); + System.exit(0); + } + + private static int dp2px(float dpValue) { + final float scale = Resources.getSystem().getDisplayMetrics().density; + return (int) (dpValue * scale + 0.5f); + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + menu.add(0, android.R.id.copy, 0, android.R.string.copy).setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM); + return super.onCreateOptionsMenu(menu); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case android.R.id.copy: + ClipboardManager cm = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE); + cm.setPrimaryClip(ClipData.newPlainText(getPackageName(), mLog)); + return true; + } + return super.onOptionsItemSelected(item); + } + + @Override + public void onBackPressed() { + restart(); + } + } +} diff --git a/app/src/main/java/com/vectras/vm/WidgetProvider.java b/app/src/main/java/com/vectras/vm/WidgetProvider.java new file mode 100644 index 0000000..4fe9895 --- /dev/null +++ b/app/src/main/java/com/vectras/vm/WidgetProvider.java @@ -0,0 +1,54 @@ +package com.vectras.vm; + +import android.app.PendingIntent; +import android.appwidget.AppWidgetManager; +import android.appwidget.AppWidgetProvider; +import android.content.Context; +import android.content.Intent; +import android.os.Build; +import android.widget.ListView; +import android.widget.RemoteViews; +import android.widget.Toast; + +import androidx.recyclerview.widget.GridLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.vectras.vm.MainRoms.AdapterMainRoms; +import com.vectras.vm.MainRoms.DataMainRoms; +import com.vectras.vm.utils.FileUtils; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; + +public class WidgetProvider extends AppWidgetProvider { + + public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { + // Perform this loop procedure for each widget that belongs to this + // provider. + for (int i=0; i < appWidgetIds.length; i++) { + int appWidgetId = appWidgetIds[i]; + // Create an Intent to launch ExampleActivity + Intent intent = new Intent(context, MainActivity.class); + PendingIntent pendingIntent = PendingIntent.getActivity( + /* context = */ context, + /* requestCode = */ 0, + /* intent = */ intent, + /* flags = */ PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE + ); + + // Get the layout for the widget and attach an onClick listener to + // the button. + RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widgetlayout); + views.setOnClickPendingIntent(R.id.button, pendingIntent); + views.setRemoteAdapter(R.id.mRVMainRoms, intent); + // Tell the AppWidgetManager to perform an update on the current app + // widget. + appWidgetManager.updateAppWidget(appWidgetId, views); + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/vectras/vm/adapter/LogsAdapter.java b/app/src/main/java/com/vectras/vm/adapter/LogsAdapter.java new file mode 100644 index 0000000..95d1607 --- /dev/null +++ b/app/src/main/java/com/vectras/vm/adapter/LogsAdapter.java @@ -0,0 +1,385 @@ +package com.vectras.vm.adapter; + +import androidx.lifecycle.Observer; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; +import androidx.recyclerview.widget.RecyclerView.AdapterDataObserver; +import com.vectras.vm.logger.LogItem; +import java.util.Collections; +import android.widget.TextView; +import android.content.Context; +import android.view.ViewGroup; +import android.view.LayoutInflater; +import java.util.Vector; +import android.database.DataSetObserver; +import java.util.Date; +import android.text.format.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Locale; +import android.os.Message; +import android.os.Bundle; +import android.os.Handler; +import android.view.View; +import com.vectras.vm.R; +import android.text.Html; +import android.view.MotionEvent; +import com.vectras.vm.logger.VectrasStatus; + +public class LogsAdapter extends RecyclerView.Adapter + implements VectrasStatus.LogListener ,Handler.Callback, + View.OnTouchListener +{ + private static final int MESSAGE_NEWLOG = 0; + + private static final int MESSAGE_CLEARLOG = 1; + + private static final int MESSAGE_NEWTS = 2; + private static final int MESSAGE_NEWLOGLEVEL = 3; + + public static final int TIME_FORMAT_NONE = 0; + public static final int TIME_FORMAT_SHORT = 1; + public static final int TIME_FORMAT_ISO = 2; + private static final int MAX_STORED_LOG_ENTRIES = 1000; + + private Vector allEntries = new Vector<>(); + + private Vector currentLevelEntries = new Vector(); + + private Handler mHandler; + private Context mContext; + private OnItemClickListener itemClickListener; + private LinearLayoutManager mLinearLayoutManager; + + private Vector observers = new Vector<>(); + + private int mTimeFormat = -100; + private int mLogLevel = 3; + private boolean mLockAutoScroll = false; + + + /** + * Interfaces + */ + + public interface OnItemClickListener + { + void onItemClick(View view, int position, String logText); + void onItemLongClick(View view, int position, String logText); + } + + public class logViewHolder extends RecyclerView.ViewHolder + { + TextView textLog; + + logViewHolder(View itemView) + { + super(itemView); + + this.textLog = itemView.findViewById(R.id.textLog); + } + } + + + public LogsAdapter(LinearLayoutManager layoutManager, + Context context) + { + this.mContext = context; + this.mLinearLayoutManager = layoutManager; + + setLogLevel(VectrasStatus.LogLevel.DEBUG.getInt()); + + initLogBuffer(); + if (mHandler == null) + { + mHandler = new Handler(this); + } + + VectrasStatus.addLogListener(this); + } + + public void setOnItemClickListener(OnItemClickListener listener) { + this.itemClickListener = listener; + } + + private void initLogBuffer() + { + allEntries.clear(); + Collections.addAll(allEntries, VectrasStatus.getlogbuffer()); + initCurrentMessages(); + } + + private void initCurrentMessages() + { + currentLevelEntries.clear(); + for (LogItem li : allEntries) + { + if (li.getLogLevel().getInt() <= mLogLevel) + currentLevelEntries.add(li); + } + } + + @Override + public logViewHolder onCreateViewHolder(ViewGroup parent, int viewType) + { + Context context = parent.getContext(); + LayoutInflater inflater = LayoutInflater.from(context); + + View logView = inflater.inflate(R.layout.list_item_log, + parent, false); + logView.setOnTouchListener(this); + + return new logViewHolder(logView); + } + + @Override + public void onBindViewHolder(final logViewHolder viewHolder, + final int position) + { + final String text; + + try + { + LogItem logItem = currentLevelEntries.get(position); + String msg = logItem.getString(mContext); + String time = getTime(logItem, mTimeFormat); + text = (!time.isEmpty() ? String.format("[%s] ", time) : "") + msg; + viewHolder.textLog.setText(Html.fromHtml(text)); + } + catch (Exception e) + { + VectrasStatus.logException(e); + return; + } + + viewHolder.textLog.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) + { + if (itemClickListener != null) + itemClickListener.onItemClick(v, position, text); + } + }); + + viewHolder.textLog.setOnLongClickListener(new View.OnLongClickListener() { + @Override + public boolean onLongClick(View v) + { + if (itemClickListener != null) + itemClickListener.onItemLongClick(v, position, text); + return true; + } + }); + } + + @Override + public void registerAdapterDataObserver(RecyclerView.AdapterDataObserver observer) + { + super.registerAdapterDataObserver(observer); + observers.add(observer); + } + + @Override + public void unregisterAdapterDataObserver(RecyclerView.AdapterDataObserver observer) + { + super.unregisterAdapterDataObserver(observer); + observers.remove(observer); + } + + @Override + public int getItemCount() + { + return currentLevelEntries.size(); + } + + @Override + public long getItemId(int position) + { + return ((Object) currentLevelEntries.get(position)).hashCode(); + } + + public boolean isEmpty() + { + return currentLevelEntries.isEmpty(); + } + + @Override + public void onAttachedToRecyclerView( + RecyclerView recyclerView) + { + super.onAttachedToRecyclerView(recyclerView); + } + + @Override + public boolean onTouch(View p1, MotionEvent event) + { + // aqui deveria pausar autoscroll + /*int action = event.getAction(); + + if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_MOVE){ + mLockAutoScroll = true; + + return true; + } + + mLockAutoScroll = false;*/ + + return false; + } + + private String getTime(LogItem le, int time) + { + if (time != TIME_FORMAT_NONE) + { + Date d = new Date(le.getLogtime()); + java.text.DateFormat timeformat; + if (time == TIME_FORMAT_SHORT) + timeformat = new SimpleDateFormat("HH:mm a"); + else + timeformat = DateFormat.getTimeFormat(mContext); + + return timeformat.format(d); + + } + else + { + return ""; + } + } + + + /** + * Handler implementação + */ + + @Override + public boolean handleMessage(Message msg) + { + // We have been called + if (msg.what == MESSAGE_NEWLOG) + { + LogItem logMessage = msg.getData().getParcelable("logmessage"); + if (addLogMessage(logMessage)) + { + + for (AdapterDataObserver observer : observers) + { + observer.onChanged(); + } + + if (!mLockAutoScroll) + scrollToLastPosition(); + } + } + else if (msg.what == MESSAGE_CLEARLOG) + { + for (AdapterDataObserver observer : observers) + { + observer.onChanged(); + } + initLogBuffer(); + } + else if (msg.what == MESSAGE_NEWTS) + { + for (AdapterDataObserver observer : observers) + { + observer.onChanged(); + } + } + else if (msg.what == MESSAGE_NEWLOGLEVEL) + { + initCurrentMessages(); + + for (AdapterDataObserver observer : observers) + { + observer.onChanged(); + } + + } + + return true; + } + + + /** + * @param logmessage + * @return True if the current entries have changed + */ + private boolean addLogMessage(LogItem logmessage) + { + allEntries.add(logmessage); + + if (allEntries.size() > MAX_STORED_LOG_ENTRIES) + { + Vector oldAllEntries = allEntries; + allEntries = new Vector(allEntries.size()); + for (int i = 50; i < oldAllEntries.size(); i++) + { + allEntries.add(oldAllEntries.elementAt(i)); + } + initCurrentMessages(); + return true; + } + else + { + if (logmessage.getLogLevel().getInt() <= mLogLevel) + { + currentLevelEntries.add(logmessage); + return true; + } + else + { + return false; + } + } + } + + public LogItem getItem(int position) + { + return currentLevelEntries.get(position); + } + + public void clearLog() + { + // Actually is probably called from GUI Thread as result of the user + // pressing a button. But better safe than sorry + VectrasStatus.clearLog(); + } + + public void scrollToLastPosition() + { + // scroll para ultima mensagem + mLinearLayoutManager.scrollToPosition( + mLinearLayoutManager.getItemCount() - 1); + } + + public void setLogLevel(int level) { + mLogLevel = level; + } + + + /** + * LogListener + */ + + @Override + public void newLog(LogItem logMessage) + { + Message msg = Message.obtain(); + + assert (msg != null); + msg.what = MESSAGE_NEWLOG; + + Bundle bundle = new Bundle(); + bundle.putParcelable("logmessage", logMessage); + + msg.setData(bundle); + mHandler.sendMessage(msg); + } + + @Override + public void onClear() + { + mHandler.sendEmptyMessage(MESSAGE_CLEARLOG); + } + +} diff --git a/app/src/main/java/com/vectras/vm/data/LoginDataSource.java b/app/src/main/java/com/vectras/vm/data/LoginDataSource.java new file mode 100644 index 0000000..11d98c2 --- /dev/null +++ b/app/src/main/java/com/vectras/vm/data/LoginDataSource.java @@ -0,0 +1,29 @@ +package com.vectras.vm.data; + +import com.vectras.vm.data.model.LoggedInUser; + +import java.io.IOException; + +/** + * Class that handles authentication w/ login credentials and retrieves user information. + */ +public class LoginDataSource { + + public Result login(String username, String password) { + + try { + // TODO: handle loggedInUser authentication + LoggedInUser fakeUser = + new LoggedInUser( + java.util.UUID.randomUUID().toString(), + "Jane Doe"); + return new Result.Success<>(fakeUser); + } catch (Exception e) { + return new Result.Error(new IOException("Error logging in", e)); + } + } + + public void logout() { + // TODO: revoke authentication + } +} \ No newline at end of file diff --git a/app/src/main/java/com/vectras/vm/data/LoginRepository.java b/app/src/main/java/com/vectras/vm/data/LoginRepository.java new file mode 100644 index 0000000..fffde4e --- /dev/null +++ b/app/src/main/java/com/vectras/vm/data/LoginRepository.java @@ -0,0 +1,54 @@ +package com.vectras.vm.data; + +import com.vectras.vm.data.model.LoggedInUser; + +/** + * Class that requests authentication and user information from the remote data source and + * maintains an in-memory cache of login status and user credentials information. + */ +public class LoginRepository { + + private static volatile LoginRepository instance; + + private LoginDataSource dataSource; + + // If user credentials will be cached in local storage, it is recommended it be encrypted + // @see https://developer.android.com/training/articles/keystore + private LoggedInUser user = null; + + // private constructor : singleton access + private LoginRepository(LoginDataSource dataSource) { + this.dataSource = dataSource; + } + + public static LoginRepository getInstance(LoginDataSource dataSource) { + if (instance == null) { + instance = new LoginRepository(dataSource); + } + return instance; + } + + public boolean isLoggedIn() { + return user != null; + } + + public void logout() { + user = null; + dataSource.logout(); + } + + private void setLoggedInUser(LoggedInUser user) { + this.user = user; + // If user credentials will be cached in local storage, it is recommended it be encrypted + // @see https://developer.android.com/training/articles/keystore + } + + public Result login(String username, String password) { + // handle login + Result result = dataSource.login(username, password); + if (result instanceof Result.Success) { + setLoggedInUser(((Result.Success) result).getData()); + } + return result; + } +} \ No newline at end of file diff --git a/app/src/main/java/com/vectras/vm/data/Result.java b/app/src/main/java/com/vectras/vm/data/Result.java new file mode 100644 index 0000000..2585d54 --- /dev/null +++ b/app/src/main/java/com/vectras/vm/data/Result.java @@ -0,0 +1,48 @@ +package com.vectras.vm.data; + +/** + * A generic class that holds a result success w/ data or an error exception. + */ +public class Result { + // hide the private constructor to limit subclass types (Success, Error) + private Result() { + } + + @Override + public String toString() { + if (this instanceof Result.Success) { + Result.Success success = (Result.Success) this; + return "Success[data=" + success.getData().toString() + "]"; + } else if (this instanceof Result.Error) { + Result.Error error = (Result.Error) this; + return "Error[exception=" + error.getError().toString() + "]"; + } + return ""; + } + + // Success sub-class + public final static class Success extends Result { + private T data; + + public Success(T data) { + this.data = data; + } + + public T getData() { + return this.data; + } + } + + // Error sub-class + public final static class Error extends Result { + private Exception error; + + public Error(Exception error) { + this.error = error; + } + + public Exception getError() { + return this.error; + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/vectras/vm/data/model/LoggedInUser.java b/app/src/main/java/com/vectras/vm/data/model/LoggedInUser.java new file mode 100644 index 0000000..0b647a5 --- /dev/null +++ b/app/src/main/java/com/vectras/vm/data/model/LoggedInUser.java @@ -0,0 +1,23 @@ +package com.vectras.vm.data.model; + +/** + * Data class that captures user information for logged in users retrieved from LoginRepository + */ +public class LoggedInUser { + + private String userId; + private String displayName; + + public LoggedInUser(String userId, String displayName) { + this.userId = userId; + this.displayName = displayName; + } + + public String getUserId() { + return userId; + } + + public String getDisplayName() { + return displayName; + } +} \ No newline at end of file diff --git a/app/src/main/java/com/vectras/vm/logger/LogItem.java b/app/src/main/java/com/vectras/vm/logger/LogItem.java new file mode 100644 index 0000000..a51b312 --- /dev/null +++ b/app/src/main/java/com/vectras/vm/logger/LogItem.java @@ -0,0 +1,211 @@ +/* + * Copyright (c) 2012-2016 Arne Schwabe + * Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt + */ + +package com.vectras.vm.logger; + +import android.os.Parcel; +import android.os.Parcelable; + +import com.vectras.vm.R; +import android.content.Context; +import java.util.Locale; +import java.util.UnknownFormatConversionException; +import java.util.FormatFlagsConversionMismatchException; +import android.annotation.SuppressLint; +import java.security.cert.CertificateFactory; +import java.security.cert.X509Certificate; +import android.content.pm.PackageManager; +import java.io.ByteArrayInputStream; +import android.content.pm.Signature; +import java.security.MessageDigest; +import java.util.Arrays; +import android.content.pm.PackageInfo; +import java.security.NoSuchAlgorithmException; +import java.security.cert.CertificateException; + +/** + * Created by arne on 24.04.16. + */ +public class LogItem implements Parcelable { + + private Object[] mArgs = null; + private String mMessage = null; + private int mResourceId; + // Default log priority + VectrasStatus.LogLevel mLevel = VectrasStatus.LogLevel.INFO; + private long logtime = System.currentTimeMillis(); + private int mVerbosityLevel = -1; + + public LogItem(int resId, Object... args) { + mResourceId = resId; + mArgs = args; + } + + public LogItem(VectrasStatus.LogLevel loglevel, int verblevel, String msg) { + mLevel = loglevel; + mMessage = msg; + mVerbosityLevel = verblevel; + } + + public LogItem(VectrasStatus.LogLevel level, int resId, Object... args) { + mLevel = level; + mResourceId = resId; + mArgs = args; + } + + public LogItem(VectrasStatus.LogLevel loglevel, String msg) { + mLevel = loglevel; + mMessage = msg; + } + + + public LogItem(VectrasStatus.LogLevel loglevel, int ressourceId) { + mResourceId = ressourceId; + mLevel = loglevel; + } + + @Override + public String toString() { + return getString(null); + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeArray(mArgs); + dest.writeString(mMessage); + dest.writeInt(mResourceId); + dest.writeInt(mLevel.getInt()); + + dest.writeLong(logtime); + } + + public LogItem(Parcel in) { + mArgs = in.readArray(Object.class.getClassLoader()); + mMessage = in.readString(); + mResourceId = in.readInt(); + mLevel = VectrasStatus.LogLevel.getEnumByValue(in.readInt()); + logtime = in.readLong(); + } + + public static final Creator CREATOR + = new Creator() { + public LogItem createFromParcel(Parcel in) { + return new LogItem(in); + } + + public LogItem[] newArray(int size) { + return new LogItem[size]; + } + }; + + public VectrasStatus.LogLevel getLogLevel() { + return mLevel; + } + + public long getLogtime() { + return logtime; + } + + public String getMessage() { + return mMessage; + } + + public String getString(Context c) { + try { + if (mMessage != null) { + return mMessage; + } else { + if (c != null) { + if (mResourceId == R.string.app_name) + return getAppInfoString(c); + else if (mArgs == null) + return c.getString(mResourceId); + else + return c.getString(mResourceId, mArgs); + } else { + String str = String.format(Locale.ENGLISH, "Log (no context) resid %d", mResourceId); + if (mArgs != null) + str += join("|", mArgs); + + return str; + } + } + } catch (UnknownFormatConversionException e) { + if (c != null) + throw new UnknownFormatConversionException(e.getLocalizedMessage() + getString(null)); + else + throw e; + } catch (java.util.FormatFlagsConversionMismatchException e) { + if (c != null) + throw new FormatFlagsConversionMismatchException(e.getLocalizedMessage() + getString(null), e.getConversion()); + else + throw e; + } + } + + //private String listb = ""; + + // The lint is wrong here + @SuppressLint("StringFormatMatches") + private String getAppInfoString(Context c) { + c.getPackageManager(); + String apksign = "error getting package signature"; + + String version = "error getting version"; + try { + @SuppressLint("PackageManagerGetSignatures") + Signature raw = c.getPackageManager().getPackageInfo(c.getPackageName(), PackageManager.GET_SIGNATURES).signatures[0]; + CertificateFactory cf = CertificateFactory.getInstance("X.509"); + X509Certificate cert = (X509Certificate) cf.generateCertificate(new ByteArrayInputStream(raw.toByteArray())); + MessageDigest md = MessageDigest.getInstance("SHA-1"); + byte[] der = cert.getEncoded(); + md.update(der); + byte[] digest = md.digest(); + if (!Arrays.equals(digest, VectrasStatus.oficialkey) && !Arrays.equals(digest, VectrasStatus.oficialdebugkey)) + apksign = ""; + PackageInfo packageinfo = c.getPackageManager().getPackageInfo(c.getPackageName(), 0); + version = String.format("%s Projeto %d", packageinfo.versionName, packageinfo.versionCode); + + } catch (PackageManager.NameNotFoundException | CertificateException | + NoSuchAlgorithmException ignored) { + } + + /* Object[] argsext = Arrays.copyOf(mArgs, mArgs.length); + argsext[argsext.length - 1] = apksign; + argsext[argsext.length - 2] = version;*/ + + return c.getString(R.string.app_name, version, apksign); + + } + + // TextUtils.join will cause not macked exeception in tests .... + public static String join(CharSequence delimiter, Object[] tokens) { + StringBuilder sb = new StringBuilder(); + boolean firstTime = true; + for (Object token : tokens) { + if (firstTime) { + firstTime = false; + } else { + sb.append(delimiter); + } + sb.append(token); + } + return sb.toString(); + } + + public int getVerbosityLevel() { + if (mVerbosityLevel == -1) { + // Hack: + // For message not from OpenVPN, report the status level as log level + return mLevel.getInt(); + } + return mVerbosityLevel; + } +} diff --git a/app/src/main/java/com/vectras/vm/logger/VMStatus.java b/app/src/main/java/com/vectras/vm/logger/VMStatus.java new file mode 100644 index 0000000..c67811a --- /dev/null +++ b/app/src/main/java/com/vectras/vm/logger/VMStatus.java @@ -0,0 +1,33 @@ +package com.vectras.vm.logger; + +import android.os.Parcel; +import android.os.Parcelable; + +public enum VMStatus implements Parcelable { + V_STARTVM, + V_STOPVM, + UNKNOWN_LEVEL; + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeInt(ordinal()); + } + + @Override + public int describeContents() { + return 0; + } + + public static final Creator CREATOR = new Creator() { + @Override + public VMStatus createFromParcel(Parcel in) { + return VMStatus.values()[in.readInt()]; + } + + @Override + public VMStatus[] newArray(int size) { + return new VMStatus[size]; + } + }; +} + diff --git a/app/src/main/java/com/vectras/vm/logger/VectrasStatus.java b/app/src/main/java/com/vectras/vm/logger/VectrasStatus.java new file mode 100644 index 0000000..b7e5aa2 --- /dev/null +++ b/app/src/main/java/com/vectras/vm/logger/VectrasStatus.java @@ -0,0 +1,355 @@ +package com.vectras.vm.logger; + +import static android.provider.Settings.System.getString; + +import java.io.StringWriter; +import java.io.PrintWriter; +import java.util.LinkedList; +import java.util.Vector; +import android.os.Build; +import com.vectras.vm.R; +import android.content.Intent; +import android.content.Context; +import android.os.Message; +import java.io.File; +import android.os.HandlerThread; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; +import java.util.Iterator; +import java.util.Locale; + +public class VectrasStatus +{ + private static final LinkedList logbuffer; + + private static Vector logListener; + private static Vector stateListener; + + private static VMStatus mLastLevel = VMStatus.V_STOPVM; + + private static String mLaststatemsg = ""; + private static String mLaststate = "NOPROCESS"; + private static int mLastStateresid = R.string.noproccesses; + private static Intent mLastIntent = null; + + + static final int MAXLOGENTRIES = 1000; + + public static boolean isVMActive() { + return mLastLevel != VMStatus.V_STOPVM && !(mLastLevel == VMStatus.V_STOPVM); + } + + public static String getLastState() { + return mLaststate; + } + + public static String getLastCleanLogMessage(Context c) { + String message = mLaststatemsg; + switch (mLastLevel) { + case V_STARTVM: + String[] parts = mLaststatemsg.split(","); + if (parts.length >= 7) + message = String.format(Locale.US, "%s %s", parts[1], parts[6]); + break; + } + + while (message.endsWith(",")) + message = message.substring(0, message.length() - 1); + + String status = mLaststate; + if (status.equals("NOPROCESS")) + return message; + + String prefix = c.getString(mLastStateresid); + if (mLastStateresid == R.string.unknownstate) + message = status + message; + if (message.length() > 0) + prefix += ": "; + + return prefix + message; + + } + + + public static enum LogLevel { + + INFO(2), + ERROR(-2), + WARNING(1), + VERBOSE(3), + DEBUG(4); + + protected int mValue; + + LogLevel(int value) { + mValue = value; + } + + public int getInt() { + return mValue; + } + + public static LogLevel getEnumByValue(int value) { + switch (value) { + case 2: + return INFO; + case -2: + return ERROR; + case 1: + return WARNING; + case 3: + return VERBOSE; + case 4: + return DEBUG; + + default: + return null; + } + } + } + + // keytool -printcert -jarfile de.blinkt.openvpn_85.apk + // tudo ok, certificado da Playstore + static final byte[] oficialkey = {93, -72, 88, 103, -128, 115, -1, -47, 120, 113, 98, -56, 12, -56, 52, -62, 95, -2, -114, 95}; + // já atualizado, slipk certificado + static final byte[] oficialdebugkey = {-41, 73, 58, 102, -81, -27, -120, 45, -56, -3, 53, -49, 119, -97, -20, -80, 65, 68, -72, -22}; + + static { + logbuffer = new LinkedList<>(); + logListener = new Vector<>(); + stateListener = new Vector<>(); + + logInformation(); + } + + + public synchronized static void clearLog() { + logbuffer.clear(); + logInformation(); + logInfo("LOGS CLEARED!"); + + for (LogListener li : logListener) { + li.onClear(); + } + } + + public synchronized static LogItem[] getlogbuffer() { + + // The stoned way of java to return an array from a vector + // brought to you by eclipse auto complete + return logbuffer.toArray(new LogItem[logbuffer.size()]); + } + + private static void logInformation() { + logInfo(R.string.app_name); + logInfo(R.string.app_version); + logInfo("MOBILE MODEL: " + Build.MODEL); + logInfo("ANDROID VERSION: " + Build.VERSION.SDK_INT); + } + + + /** + * Listeners + */ + + public interface LogListener { + void newLog(LogItem logItem); + void onClear(); + } + + public interface StateListener { + void updateState(String state, String logMessage, int localizedResId, VMStatus level, Intent intent); + } + + public synchronized static void addLogListener(LogListener ll) { + if (!logListener.contains(ll)) { + logListener.add(ll); + } + } + + public synchronized static void removeLogListener(LogListener ll) { + if (logListener.contains(ll)) { + logListener.remove(ll); + } + } + + public synchronized static void addStateListener(StateListener sl) { + if (!stateListener.contains(sl)) { + stateListener.add(sl); + if (mLaststate != null) + sl.updateState(mLaststate, mLaststatemsg, mLastStateresid, mLastLevel, mLastIntent); + } + } + + public synchronized static void removeStateListener(StateListener sl) { + if (stateListener.contains(sl)) { + stateListener.remove(sl); + } + } + + + /** + * State + */ + + public static final String + V_STARTVM = "STARTING VM", + V_STOPVM = "STOPPING VM"; + + public static int getLocalizedState(String state) { + switch (state) { + case V_STARTVM: + return R.string.startvm; + case V_STOPVM: + return R.string.stopvm; + } + return R.string.unknownstate; + } + + private static VMStatus getLevel(String state) { + String[] noreplyet = {V_STARTVM, V_STOPVM}; + String[] reply = {V_STARTVM, V_STOPVM}; + String[] startedvm = {V_STARTVM}; + String[] stoppedvm = {V_STOPVM}; + + for (String x : noreplyet) + if (state.equals(x)) + return VMStatus.V_STARTVM; + + for (String x : reply) + if (state.equals(x)) + return VMStatus.V_STOPVM; + + for (String x : startedvm) + if (state.equals(x)) + return VMStatus.V_STARTVM; + + for (String x : stoppedvm) + if (state.equals(x)) + return VMStatus.V_STOPVM; + + return VMStatus.UNKNOWN_LEVEL; + } + + public static void updateStateString(String state, String msg) { + int rid = getLocalizedState(state); + VMStatus level = getLevel(state); + updateStateString(state, msg, rid, level); + } + + public synchronized static void updateStateString(String state, String msg, int resid, VMStatus level) + { + updateStateString(state, msg, resid, level, null); + } + + public synchronized static void updateStateString(String state, String msg, int resid, VMStatus level, Intent intent) { + // Workound for OpenVPN doing AUTH and wait and being startedvm + // Simply ignore these state + /*if (mLastLevel == VMStatus.LEVEL_CONNECTED && + (state.equals(SSH_AUTHENTICATING))) { + newLogItem(new LogItem((LogLevel.DEBUG), String.format("Ignoring SocksHttp Status in CONNECTED state (%s->%s): %s", state, level.toString(), msg))); + return; + }*/ + + mLaststate = state; + mLaststatemsg = msg; + mLastStateresid = resid; + mLastLevel = level; + mLastIntent = intent; + + + for (StateListener sl : stateListener) { + sl.updateState(state, msg, resid, level, intent); + } + + //newLogItem(new LogItem((LogLevel.DEBUG), String.format("SocksHttp Novo Status (%s->%s): %s",state,level.toString(),msg))); + } + + + /** + * NewLog + */ + + static void newLogItem(LogItem logItem) { + newLogItem(logItem, false); + } + + synchronized static void newLogItem(LogItem logItem, boolean cachedLine) { + if (cachedLine) { + logbuffer.addFirst(logItem); + } else { + logbuffer.addLast(logItem); + } + + if (logbuffer.size() > MAXLOGENTRIES + MAXLOGENTRIES / 2) { + while (logbuffer.size() > MAXLOGENTRIES) + logbuffer.removeFirst(); + } + + for (LogListener ll : logListener) { + ll.newLog(logItem); + } + } + + + /** + * Logger static methods + */ + + public static void logException(String context, String e) { + logException(LogLevel.ERROR, context, e); + } + + public static void logException(LogLevel ll, String context, String e) { + + LogItem li; + + if (context != null) + li = new LogItem(ll, String.format("%s: %s", context, e)); + else + li = new LogItem(ll, String.format("Error: %s", e)); + + newLogItem(li); + } + + public static void logException(Exception e) { + logException(LogLevel.ERROR, null, e.getMessage()); + } + + public static void logInfo(String message) { + newLogItem(new LogItem(LogLevel.INFO, message)); + } + + public static void logDebug(String message) { + newLogItem(new LogItem(LogLevel.DEBUG, message)); + } + + public static void logInfo(int resourceId, Object... args) { + newLogItem(new LogItem(LogLevel.INFO, resourceId, args)); + } + + public static void logDebug(int resourceId, Object... args) { + newLogItem(new LogItem(LogLevel.DEBUG, resourceId, args)); + } + + public static void logError(String msg) { + newLogItem(new LogItem(LogLevel.ERROR, msg)); + } + + public static void logWarning(int resourceId, Object... args) { + newLogItem(new LogItem(LogLevel.WARNING, resourceId, args)); + } + + public static void logWarning(String msg) { + newLogItem(new LogItem(LogLevel.WARNING, msg)); + } + + public static void logError(int resourceId) { + newLogItem(new LogItem(LogLevel.ERROR, resourceId)); + } + + public static void logError(int resourceId, Object... args) { + newLogItem(new LogItem(LogLevel.ERROR, resourceId, args)); + } + +} diff --git a/app/src/main/java/com/vectras/vm/ui/login/GoogleSignInActivity.java b/app/src/main/java/com/vectras/vm/ui/login/GoogleSignInActivity.java new file mode 100644 index 0000000..2a45c76 --- /dev/null +++ b/app/src/main/java/com/vectras/vm/ui/login/GoogleSignInActivity.java @@ -0,0 +1,205 @@ +package com.vectras.vm.ui.login; + +import android.app.ProgressDialog; +import android.content.Intent; +import android.os.Bundle; +import android.util.Log; +import android.view.View; +import android.widget.TextView; + +import androidx.appcompat.app.AppCompatActivity; + +import com.google.android.gms.auth.api.Auth; +import com.google.android.gms.auth.api.signin.GoogleSignInAccount; +import com.google.android.gms.auth.api.signin.GoogleSignInOptions; +import com.google.android.gms.auth.api.signin.GoogleSignInResult; +import com.google.android.gms.common.ConnectionResult; +import com.google.android.gms.common.SignInButton; +import com.google.android.gms.common.api.GoogleApiClient; +import com.google.android.gms.common.api.OptionalPendingResult; +import com.google.android.gms.common.api.ResultCallback; +import com.google.android.gms.common.api.Status; +import com.vectras.vm.R; +import com.vectras.vm.RomsManagerActivity; + +/** + * Activity to demonstrate basic retrieval of the Google user's ID, email address, and basic + * profile. + */ +public class GoogleSignInActivity extends AppCompatActivity implements + GoogleApiClient.OnConnectionFailedListener, + View.OnClickListener { + + private static final String TAG = "GoogleSignInActivity"; + private static final int RC_SIGN_IN = 9001; + + private GoogleApiClient mGoogleApiClient; + private TextView mStatusTextView; + private ProgressDialog mProgressDialog; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_google_sign_in); + + // Views + mStatusTextView = (TextView) findViewById(R.id.status); + + // Button listeners + findViewById(R.id.sign_in_button).setOnClickListener(this); + findViewById(R.id.sign_out_button).setOnClickListener(this); + findViewById(R.id.disconnect_button).setOnClickListener(this); + + // [START configure_signin] + // Configure sign-in to request the user's ID, email address, and basic + // profile. ID and basic profile are included in DEFAULT_SIGN_IN. + GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN) + .requestEmail() + .build(); + // [END configure_signin] + + // [START build_client] + // Build a GoogleApiClient with access to the Google Sign-In API and the + // options specified by gso. + mGoogleApiClient = new GoogleApiClient.Builder(this) + .enableAutoManage(this /* FragmentActivity */, this /* OnConnectionFailedListener */) + .addApi(Auth.GOOGLE_SIGN_IN_API, gso) + .build(); + // [END build_client] + + // [START customize_button] + // Set the dimensions of the sign-in button. + SignInButton signInButton = (SignInButton) findViewById(R.id.sign_in_button); + signInButton.setSize(SignInButton.SIZE_STANDARD); + // [END customize_button] + } + + @Override + public void onStart() { + super.onStart(); + + OptionalPendingResult opr = Auth.GoogleSignInApi.silentSignIn(mGoogleApiClient); + if (opr.isDone()) { + // If the user's cached credentials are valid, the OptionalPendingResult will be "done" + // and the GoogleSignInResult will be available instantly. + Log.d(TAG, "Got cached sign-in"); + GoogleSignInResult result = opr.get(); + handleSignInResult(result); + } else { + // If the user has not previously signed in on this device or the sign-in has expired, + // this asynchronous branch will attempt to sign in the user silently. Cross-device + // single sign-on will occur in this branch. + showProgressDialog(); + opr.setResultCallback(new ResultCallback() { + @Override + public void onResult(GoogleSignInResult googleSignInResult) { + hideProgressDialog(); + handleSignInResult(googleSignInResult); + } + }); + } + } + + // [START onActivityResult] + @Override + public void onActivityResult(int requestCode, int resultCode, Intent data) { + super.onActivityResult(requestCode, resultCode, data); + + // Result returned from launching the Intent from GoogleSignInApi.getSignInIntent(...); + if (requestCode == RC_SIGN_IN) { + GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(data); + handleSignInResult(result); + } + } + // [END onActivityResult] + + // [START handleSignInResult] + private void handleSignInResult(GoogleSignInResult result) { + Log.d(TAG, "handleSignInResult:" + result.isSuccess()); + if (result.isSuccess()) { + // Signed in successfully, show authenticated UI. + GoogleSignInAccount acct = result.getSignInAccount(); + mStatusTextView.setText(getString(Integer.parseInt(acct.getDisplayName()))); + updateUI(true); + } else { + // Signed out, show unauthenticated UI. + updateUI(false); + } + } + // [END handleSignInResult] + + // [START signIn] + private void signIn() { + Intent signInIntent = Auth.GoogleSignInApi.getSignInIntent(mGoogleApiClient); + startActivityForResult(signInIntent, RC_SIGN_IN); + } + // [END signIn] + + // [START signOut] + private void signOut() { + Auth.GoogleSignInApi.signOut(mGoogleApiClient).setResultCallback( + new ResultCallback() { + @Override + public void onResult(Status status) { + // [START_EXCLUDE] + updateUI(false); + // [END_EXCLUDE] + } + }); + } + // [END signOut] + + // [START revokeAccess] + private void revokeAccess() { + Auth.GoogleSignInApi.revokeAccess(mGoogleApiClient).setResultCallback( + new ResultCallback() { + @Override + public void onResult(Status status) { + // [START_EXCLUDE] + updateUI(false); + // [END_EXCLUDE] + } + }); + } + // [END revokeAccess] + + @Override + public void onConnectionFailed(ConnectionResult connectionResult) { + // An unresolvable error has occurred and Google APIs (including Sign-In) will not + // be available. + Log.d(TAG, "onConnectionFailed:" + connectionResult); + } + + private void showProgressDialog() { + if (mProgressDialog == null) { + mProgressDialog = new ProgressDialog(this); + mProgressDialog.setMessage("Loading..."); + mProgressDialog.setIndeterminate(true); + } + + mProgressDialog.show(); + } + + private void hideProgressDialog() { + if (mProgressDialog != null && mProgressDialog.isShowing()) { + mProgressDialog.hide(); + } + } + + private void updateUI(boolean signedIn) { + if (signedIn) + startActivity(new Intent(GoogleSignInActivity.this, RomsManagerActivity.class)); + } + + @Override + public void onClick(View v) { + int id = v.getId(); + if (id == R.id.sign_in_button) { + signIn(); + } else if (id == R.id.sign_out_button) { + signOut(); + } else if (id == R.id.disconnect_button) { + revokeAccess(); + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/vectras/vm/ui/login/LoginActivity.java b/app/src/main/java/com/vectras/vm/ui/login/LoginActivity.java new file mode 100644 index 0000000..7aa3bd7 --- /dev/null +++ b/app/src/main/java/com/vectras/vm/ui/login/LoginActivity.java @@ -0,0 +1,150 @@ +package com.vectras.vm.ui.login; + +import android.app.ProgressDialog; +import android.content.Intent; +import android.net.Uri; +import android.os.Bundle; + +import androidx.annotation.NonNull; +import androidx.appcompat.app.AppCompatActivity; + +import android.text.Editable; +import android.text.TextWatcher; +import android.util.Log; +import android.view.KeyEvent; +import android.view.inputmethod.EditorInfo; +import android.widget.TextView; +import android.widget.Toast; + +import com.google.android.gms.auth.api.Auth; +import com.google.android.gms.auth.api.signin.GoogleSignInAccount; +import com.google.android.gms.auth.api.signin.GoogleSignInOptions; +import com.google.android.gms.auth.api.signin.GoogleSignInResult; +import com.google.android.gms.common.ConnectionResult; +import com.google.android.gms.common.api.GoogleApiClient; +import com.google.android.gms.common.api.ResultCallback; +import com.google.android.gms.common.api.Status; +import com.google.android.gms.tasks.OnCompleteListener; +import com.google.android.gms.tasks.Task; +import com.google.android.material.button.MaterialButton; +import com.google.android.material.textfield.TextInputEditText; +import com.google.firebase.auth.AuthResult; +import com.google.firebase.auth.FirebaseAuth; +import com.google.firebase.auth.FirebaseUser; +import com.google.firebase.auth.UserProfileChangeRequest; +import com.vectras.vm.R; +import com.vectras.vm.RomsManagerActivity; + +public class LoginActivity extends AppCompatActivity { + + private FirebaseAuth mAuth; + private TextView mStatusTextView; + // ... + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + setContentView(R.layout.activity_login); + + MaterialButton signinButton = findViewById(R.id.signinBtn); + + MaterialButton signupButton = findViewById(R.id.signupBtn); + + MaterialButton signwithGoogleButton = findViewById(R.id.signwithGoogleBtn); + + TextInputEditText usernameEditText = findViewById(R.id.username); + + TextInputEditText passwordEditText = findViewById(R.id.password); + + mStatusTextView = findViewById(R.id.errorTxt); + +// Initialize Firebase Auth + mAuth = FirebaseAuth.getInstance(); + TextWatcher afterTextChangedListener = new TextWatcher() { + @Override + public void beforeTextChanged(CharSequence s, int start, int count, int after) { + // ignore + } + + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) { + // ignore + } + + @Override + public void afterTextChanged(Editable s) { + if (usernameEditText.getText().toString().trim().length() > 0) { + signinButton.setEnabled(true); + } else { + signinButton.setEnabled(false); + } + if (passwordEditText.getText().toString().trim().length() > 0) { + signinButton.setEnabled(true); + } else { + signinButton.setEnabled(false); + } + } + }; + usernameEditText.addTextChangedListener(afterTextChangedListener); + passwordEditText.addTextChangedListener(afterTextChangedListener); + passwordEditText.setOnEditorActionListener(new TextView.OnEditorActionListener() { + + @Override + public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { + if (actionId == EditorInfo.IME_ACTION_DONE) { + + } + return false; + } + }); + + signinButton.setOnClickListener(v -> mAuth.signInWithEmailAndPassword(usernameEditText.getText().toString(), passwordEditText.getText().toString()) + .addOnCompleteListener(LoginActivity.this, (OnCompleteListener) task -> { + if (task.isSuccessful()) { + // Sign in success, update UI with the signed-in user's information + FirebaseUser user = mAuth.getCurrentUser(); + updateUI(user); + } else { + + mStatusTextView.setText(task.getException().toString()); + // If sign in fails, display a message to the user. + Toast.makeText(LoginActivity.this, "Authentication failed.", + Toast.LENGTH_SHORT).show(); + updateUI(null); + } + })); + signupButton.setOnClickListener(v -> startActivity(new Intent(this, SignupActivity.class))); + signwithGoogleButton.setOnClickListener(v -> startActivity(new Intent(this, GoogleSignInActivity.class))); + + } + + public void updateUI(Object USER) { + if (USER != null) { + FirebaseAuth auth = FirebaseAuth.getInstance(); + FirebaseUser user = auth.getCurrentUser(); + + if (user != null && !user.isEmailVerified()) { + user.sendEmailVerification() + .addOnCompleteListener(new OnCompleteListener() { + @Override + public void onComplete(@NonNull Task task) { + startActivity(new Intent(LoginActivity.this, RomsManagerActivity.class)); + } + }); + } + if (user != null && user.isEmailVerified()) + startActivity(new Intent(LoginActivity.this, RomsManagerActivity.class)); + } + } + + @Override + public void onStart() { + super.onStart(); + // Check if user is signed in (non-null) and update UI accordingly. + FirebaseUser currentUser = mAuth.getCurrentUser(); + if (currentUser != null) { + currentUser.reload(); + } + updateUI(currentUser); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/vectras/vm/ui/login/SignupActivity.java b/app/src/main/java/com/vectras/vm/ui/login/SignupActivity.java new file mode 100644 index 0000000..6fe6122 --- /dev/null +++ b/app/src/main/java/com/vectras/vm/ui/login/SignupActivity.java @@ -0,0 +1,140 @@ +package com.vectras.vm.ui.login; + +import androidx.annotation.NonNull; +import androidx.appcompat.app.AppCompatActivity; + +import android.content.Intent; +import android.net.Uri; +import android.os.Bundle; +import android.text.Editable; +import android.text.TextWatcher; +import android.util.Log; +import android.view.KeyEvent; +import android.view.inputmethod.EditorInfo; +import android.widget.TextView; +import android.widget.Toast; + +import com.google.android.gms.tasks.OnCompleteListener; +import com.google.android.gms.tasks.Task; +import com.google.android.material.button.MaterialButton; +import com.google.android.material.textfield.TextInputEditText; +import com.google.firebase.auth.FirebaseAuth; +import com.google.firebase.auth.FirebaseUser; +import com.google.firebase.auth.UserProfileChangeRequest; +import com.vectras.vm.R; +import com.vectras.vm.RomsManagerActivity; + +public class SignupActivity extends AppCompatActivity { + + private FirebaseAuth mAuth; + private TextView mStatusTextView; + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_signup); + + MaterialButton signupButton = findViewById(R.id.signupBtn); + + TextInputEditText fullNameEditText = findViewById(R.id.fullName); + + TextInputEditText usernameEditText = findViewById(R.id.username); + + TextInputEditText passwordEditText = findViewById(R.id.password); + + mStatusTextView = findViewById(R.id.errorTxt); + +// Initialize Firebase Auth + mAuth = FirebaseAuth.getInstance(); + TextWatcher afterTextChangedListener = new TextWatcher() { + @Override + public void beforeTextChanged(CharSequence s, int start, int count, int after) { + // ignore + } + + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) { + // ignore + } + + @Override + public void afterTextChanged(Editable s) { + if (usernameEditText.getText().toString().trim().length() > 0) { + signupButton.setEnabled(true); + } else { + signupButton.setEnabled(false); + } + if (passwordEditText.getText().toString().trim().length() > 0) { + signupButton.setEnabled(true); + } else { + signupButton.setEnabled(false); + } + if (fullNameEditText.getText().toString().trim().length() > 0) { + signupButton.setEnabled(true); + } else { + signupButton.setEnabled(false); + } + } + }; + fullNameEditText.addTextChangedListener(afterTextChangedListener); + usernameEditText.addTextChangedListener(afterTextChangedListener); + passwordEditText.addTextChangedListener(afterTextChangedListener); + passwordEditText.setOnEditorActionListener(new TextView.OnEditorActionListener() { + + @Override + public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { + if (actionId == EditorInfo.IME_ACTION_DONE) { + + } + return false; + } + }); + signupButton.setOnClickListener(v -> mAuth.createUserWithEmailAndPassword(usernameEditText.getText().toString(), passwordEditText.getText().toString()) + .addOnCompleteListener(SignupActivity.this, task -> { + if (task.isSuccessful()) { + // Sign in success, update UI with the signed-in user's information + Log.d("SIGNUP", "createUserWithEmail:success"); + FirebaseUser user = mAuth.getCurrentUser(); + updateUI(user); + } else { + // If sign in fails, display a message to the user. + Log.w("SIGNUP", "createUserWithEmail:failure", task.getException()); + + mStatusTextView.setText(task.getException().toString()); + + Toast.makeText(SignupActivity.this, "Authentication failed.", + Toast.LENGTH_SHORT).show(); + updateUI(null); + } + })); + } + public void updateUI(Object USER) { + if (USER != null) { + FirebaseAuth auth = FirebaseAuth.getInstance(); + FirebaseUser user = auth.getCurrentUser(); + + if (user != null && !user.isEmailVerified()) { + TextInputEditText fullNameEditText = findViewById(R.id.fullName); + UserProfileChangeRequest profileUpdates = new UserProfileChangeRequest.Builder() + .setDisplayName(String.valueOf(fullNameEditText.getText())) + .build(); + + user.updateProfile(profileUpdates) + .addOnCompleteListener(new OnCompleteListener() { + @Override + public void onComplete(@NonNull Task task) { + if (task.isSuccessful()) { + user.sendEmailVerification() + .addOnCompleteListener(new OnCompleteListener() { + @Override + public void onComplete(@NonNull Task task) { + startActivity(new Intent(SignupActivity.this, RomsManagerActivity.class)); + } + }); + + } + } + }); + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/vectras/vm/utils/AppUpdater.java b/app/src/main/java/com/vectras/vm/utils/AppUpdater.java new file mode 100644 index 0000000..c4a56f2 --- /dev/null +++ b/app/src/main/java/com/vectras/vm/utils/AppUpdater.java @@ -0,0 +1,81 @@ +package com.vectras.vm.utils; + +import android.app.ProgressDialog; +import android.content.Context; +import android.os.AsyncTask; +import com.vectras.vm.AppConfig; +import com.vectras.vm.R; +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.net.HttpURLConnection; +import java.net.URL; + +public class AppUpdater extends AsyncTask { + + private Context context; + private OnUpdateListener listener; + private ProgressDialog progressDialog; + private boolean isOnCreate; + + public AppUpdater(Context context, OnUpdateListener listener) { + this.context = context; + this.listener = listener; + } + + public void start(boolean isOnCreate) { + this.isOnCreate = isOnCreate; + execute(); + } + + public interface OnUpdateListener { + void onUpdateListener(String result); + } + + @Override + protected String doInBackground(String... strings) { + try { + StringBuilder sb = new StringBuilder(); + URL url = new URL(AppConfig.updateJson); + HttpURLConnection conn = (HttpURLConnection) url.openConnection(); + conn.setConnectTimeout(30000); + conn.setReadTimeout(30000); + conn.setRequestMethod("GET"); + conn.connect(); + + BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream())); + String response; + + while ((response = br.readLine()) != null) { + sb.append(response); + } + return sb.toString(); + } catch (Exception e) { + e.printStackTrace(); + return "Error on getting data: " + e.getMessage(); + + } + } + + @Override + protected void onPreExecute() { + super.onPreExecute(); + if (isOnCreate) { + progressDialog = new ProgressDialog(context, R.style.MainDialogTheme); + progressDialog.setMessage("Please wait for the check"); + progressDialog.setTitle("Looking for Update"); + progressDialog.setCancelable(false); + progressDialog.show(); + } + } + + @Override + protected void onPostExecute(String s) { + super.onPostExecute(s); + if (isOnCreate && progressDialog != null) { + progressDialog.dismiss(); + } + if (listener != null) { + listener.onUpdateListener(s); + } + } +} diff --git a/app/src/main/java/com/vectras/vm/utils/FileUtils.java b/app/src/main/java/com/vectras/vm/utils/FileUtils.java new file mode 100644 index 0000000..f1a7ad7 --- /dev/null +++ b/app/src/main/java/com/vectras/vm/utils/FileUtils.java @@ -0,0 +1,605 @@ +package com.vectras.vm.utils; + +import android.annotation.SuppressLint; +import android.content.ContentUris; +import android.content.Context; +import android.content.Intent; +import android.database.Cursor; +import android.net.Uri; +import android.os.Build; +import android.os.Environment; +import android.provider.DocumentsContract; +import android.provider.MediaStore; +import android.provider.OpenableColumns; +import android.text.TextUtils; +import android.util.Log; +import android.webkit.MimeTypeMap; +import android.widget.Toast; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; + +import android.app.Activity; +import android.content.Context; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.net.Uri; +import android.os.Handler; +import android.os.Looper; +import android.os.ParcelFileDescriptor; +import android.util.Log; +import android.widget.Toast; +import com.vectras.vm.MainActivity; +import com.vectras.vm.AppConfig; +import java.io.BufferedReader; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStreamWriter; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.HashMap; + +/** + * + * @author dev + */ +public class FileUtils { + + private static Uri contentUri = null; + + @SuppressLint("NewApi") + public static String getPath(Context context, final Uri uri) { + // check here to KITKAT or new version + final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT; + String selection = null; + String[] selectionArgs = null; + // DocumentProvider + if (isKitKat ) { + // ExternalStorageProvider + + if (isExternalStorageDocument(uri)) { + final String docId = DocumentsContract.getDocumentId(uri); + final String[] split = docId.split(":"); + final String type = split[0]; + + String fullPath = getPathFromExtSD(split); + if (fullPath != "") { + return fullPath; + } else { + return null; + } + } + + + // DownloadsProvider + + if (isDownloadsDocument(uri)) { + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + final String id; + Cursor cursor = null; + try { + cursor = context.getContentResolver().query(uri, new String[]{MediaStore.MediaColumns.DISPLAY_NAME}, null, null, null); + if (cursor != null && cursor.moveToFirst()) { + String fileName = cursor.getString(0); + String path = Environment.getExternalStorageDirectory().toString() + "/Download/" + fileName; + if (!TextUtils.isEmpty(path)) { + return path; + } + } + } + finally { + if (cursor != null) + cursor.close(); + } + id = DocumentsContract.getDocumentId(uri); + if (!TextUtils.isEmpty(id)) { + if (id.startsWith("raw:")) { + return id.replaceFirst("raw:", ""); + } + String[] contentUriPrefixesToTry = new String[]{ + "content://downloads/public_downloads", + "content://downloads/my_downloads" + }; + for (String contentUriPrefix : contentUriPrefixesToTry) { + try { + final Uri contentUri = ContentUris.withAppendedId(Uri.parse(contentUriPrefix), Long.valueOf(id)); + + + return getDataColumn(context, contentUri, null, null); + } catch (NumberFormatException e) { + //In Android 8 and Android P the id is not a number + return uri.getPath().replaceFirst("^/document/raw:", "").replaceFirst("^raw:", ""); + } + } + + + } + } + else { + final String id = DocumentsContract.getDocumentId(uri); + + if (id.startsWith("raw:")) { + return id.replaceFirst("raw:", ""); + } + try { + contentUri = ContentUris.withAppendedId( + Uri.parse("content://downloads/public_downloads"), Long.valueOf(id)); + } + catch (NumberFormatException e) { + e.printStackTrace(); + } + if (contentUri != null) { + + return getDataColumn(context, contentUri, null, null); + } + } + } + + + // MediaProvider + if (isMediaDocument(uri)) { + final String docId = DocumentsContract.getDocumentId(uri); + final String[] split = docId.split(":"); + final String type = split[0]; + + Uri contentUri = null; + + if ("image".equals(type)) { + contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI; + } else if ("video".equals(type)) { + contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI; + } else if ("audio".equals(type)) { + contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI; + } + selection = "_id=?"; + selectionArgs = new String[]{split[1]}; + + + return getDataColumn(context, contentUri, selection, + selectionArgs); + } + + if (isGoogleDriveUri(uri)) { + return getDriveFilePath(context, uri); + } + + if(isWhatsAppFile(uri)){ + return getFilePathForWhatsApp(context, uri); + } + + + if ("content".equalsIgnoreCase(uri.getScheme())) { + + if (isGooglePhotosUri(uri)) { + return uri.getLastPathSegment(); + } + if (isGoogleDriveUri(uri)) { + return getDriveFilePath(context, uri); + } + if( Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) + { + + // return getFilePathFromURI(context,uri); + return copyFileToInternalStorage(context, uri,"userfiles"); + // return getRealPathFromURI(context,uri); + } + else + { + return getDataColumn(context, uri, null, null); + } + + } + if ("file".equalsIgnoreCase(uri.getScheme())) { + return uri.getPath(); + } + } + else { + + if(isWhatsAppFile(uri)){ + return getFilePathForWhatsApp(context, uri); + } + + if ("content".equalsIgnoreCase(uri.getScheme())) { + String[] projection = { + MediaStore.Images.Media.DATA + }; + Cursor cursor = null; + try { + cursor = context.getContentResolver() + .query(uri, projection, selection, selectionArgs, null); + int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA); + if (cursor.moveToFirst()) { + return cursor.getString(column_index); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + } + + + + + return null; + } + + private static boolean fileExists(String filePath) { + File file = new File(filePath); + + return file.exists(); + } + + private static String getPathFromExtSD(String[] pathData) { + final String type = pathData[0]; + final String relativePath = "/" + pathData[1]; + String fullPath = ""; + + // on my Sony devices (4.4.4 & 5.1.1), `type` is a dynamic string + // something like "71F8-2C0A", some kind of unique id per storage + // don't know any API that can get the root path of that storage based on its id. + // + // so no "primary" type, but let the check here for other devices + if ("primary".equalsIgnoreCase(type)) { + fullPath = Environment.getExternalStorageDirectory() + relativePath; + if (fileExists(fullPath)) { + return fullPath; + } + } + + // Environment.isExternalStorageRemovable() is `true` for external and internal storage + // so we cannot relay on it. + // + // instead, for each possible path, check if file exists + // we'll start with secondary storage as this could be our (physically) removable sd card + fullPath = System.getenv("SECONDARY_STORAGE") + relativePath; + if (fileExists(fullPath)) { + return fullPath; + } + + fullPath = System.getenv("EXTERNAL_STORAGE") + relativePath; + if (fileExists(fullPath)) { + return fullPath; + } + + return fullPath; + } + + private static String getDriveFilePath(Context context, Uri uri) { + Uri returnUri = uri; + Cursor returnCursor = context.getContentResolver().query(returnUri, null, null, null, null); + /* + * Get the column indexes of the data in the Cursor, + * * move to the first row in the Cursor, get the data, + * * and display it. + * */ + int nameIndex = returnCursor.getColumnIndex(OpenableColumns.DISPLAY_NAME); + int sizeIndex = returnCursor.getColumnIndex(OpenableColumns.SIZE); + returnCursor.moveToFirst(); + String name = (returnCursor.getString(nameIndex)); + String size = (Long.toString(returnCursor.getLong(sizeIndex))); + File file = new File(context.getCacheDir(), name); + try { + InputStream inputStream = context.getContentResolver().openInputStream(uri); + FileOutputStream outputStream = new FileOutputStream(file); + int read = 0; + int maxBufferSize = 1 * 1024 * 1024; + int bytesAvailable = inputStream.available(); + + //int bufferSize = 1024; + int bufferSize = Math.min(bytesAvailable, maxBufferSize); + + final byte[] buffers = new byte[bufferSize]; + while ((read = inputStream.read(buffers)) != -1) { + outputStream.write(buffers, 0, read); + } + Log.e("File Size", "Size " + file.length()); + inputStream.close(); + outputStream.close(); + Log.e("File Path", "Path " + file.getPath()); + Log.e("File Size", "Size " + file.length()); + } catch (Exception e) { + Log.e("Exception", e.getMessage()); + } + return file.getPath(); + } + + /*** + * Used for Android Q+ + * @param uri + * @param newDirName if you want to create a directory, you can set this variable + * @return + */ + private static String copyFileToInternalStorage(Context context, Uri uri, String newDirName) { + Uri returnUri = uri; + + Cursor returnCursor = context.getContentResolver().query(returnUri, new String[]{ + OpenableColumns.DISPLAY_NAME,OpenableColumns.SIZE + }, null, null, null); + + + /* + * Get the column indexes of the data in the Cursor, + * * move to the first row in the Cursor, get the data, + * * and display it. + * */ + int nameIndex = returnCursor.getColumnIndex(OpenableColumns.DISPLAY_NAME); + int sizeIndex = returnCursor.getColumnIndex(OpenableColumns.SIZE); + returnCursor.moveToFirst(); + String name = (returnCursor.getString(nameIndex)); + String size = (Long.toString(returnCursor.getLong(sizeIndex))); + + File output; + if(!newDirName.equals("")) { + File dir = new File(context.getFilesDir() + "/" + newDirName); + if (!dir.exists()) { + dir.mkdir(); + } + output = new File(context.getFilesDir() + "/" + newDirName + "/" + name); + } + else{ + output = new File(context.getFilesDir() + "/" + name); + } + try { + InputStream inputStream = context.getContentResolver().openInputStream(uri); + FileOutputStream outputStream = new FileOutputStream(output); + int read = 0; + int bufferSize = 1024; + final byte[] buffers = new byte[bufferSize]; + while ((read = inputStream.read(buffers)) != -1) { + outputStream.write(buffers, 0, read); + } + + inputStream.close(); + outputStream.close(); + + } + catch (Exception e) { + + Log.e("Exception", e.getMessage()); + } + + return output.getPath(); + } + + private static String getFilePathForWhatsApp(Context context, Uri uri){ + return copyFileToInternalStorage(context, uri,"whatsapp"); + } + + private static String getDataColumn(Context context, Uri uri, String selection, String[] selectionArgs) { + Cursor cursor = null; + final String column = "_data"; + final String[] projection = {column}; + + try { + cursor = context.getContentResolver().query(uri, projection, + selection, selectionArgs, null); + + if (cursor != null && cursor.moveToFirst()) { + final int index = cursor.getColumnIndexOrThrow(column); + return cursor.getString(index); + } + } + finally { + if (cursor != null) + cursor.close(); + } + + return null; + } + + private static boolean isExternalStorageDocument(Uri uri) { + return "com.android.externalstorage.documents".equals(uri.getAuthority()); + } + + private static boolean isDownloadsDocument(Uri uri) { + return "com.android.providers.downloads.documents".equals(uri.getAuthority()); + } + + private static boolean isMediaDocument(Uri uri) { + return "com.android.providers.media.documents".equals(uri.getAuthority()); + } + + private static boolean isGooglePhotosUri(Uri uri) { + return "com.google.android.apps.photos.content".equals(uri.getAuthority()); + } + + public static boolean isWhatsAppFile(Uri uri){ + return "com.whatsapp.provider.media".equals(uri.getAuthority()); + } + + private static boolean isGoogleDriveUri(Uri uri) { + return "com.google.android.apps.docs.storage".equals(uri.getAuthority()) || "com.google.android.apps.docs.storage.legacy".equals(uri.getAuthority()); + } + + + public String LoadFile(Activity activity, String fileName, boolean loadFromRawFolder) throws IOException { + // Create a InputStream to read the file into + InputStream iS; + if (loadFromRawFolder) { + // get the resource id from the file name + int rID = activity.getResources().getIdentifier(getClass().getPackage().getName() + ":raw/" + fileName, + null, null); + // get the file as a stream + iS = activity.getResources().openRawResource(rID); + } else { + // get the file as a stream + iS = activity.getResources().getAssets().open(fileName); + } + + ByteArrayOutputStream oS = new ByteArrayOutputStream(); + byte[] buffer = new byte[iS.available()]; + int bytesRead = 0; + while ((bytesRead = iS.read(buffer)) > 0) { + oS.write(buffer); + } + oS.close(); + iS.close(); + + // return the output stream as a String + return oS.toString(); + } + + public static void saveFileContents(String dBFile, String machinesToExport) { + // TODO Auto-generated method stub + byteArrayToFile(machinesToExport.getBytes(), new File(dBFile)); + } + + public static void byteArrayToFile(byte[] byteData, File filePath) { + + try { + FileOutputStream fos = new FileOutputStream(filePath); + fos.write(byteData); + fos.close(); + + } catch (FileNotFoundException ex) { + System.out.println("FileNotFoundException : " + ex); + } catch (IOException ioe) { + System.out.println("IOException : " + ioe); + } + + } + + public static String getDataDir() { + + String dataDir = MainActivity.activity.getApplicationInfo().dataDir; + PackageManager m = MainActivity.activity.getPackageManager(); + String packageName = MainActivity.activity.getPackageName(); + Log.v("VMExecutor", "Found packageName: " + packageName); + + if (dataDir == null) { + dataDir = "/data/data/" + packageName; + } + return dataDir; + } + + public static boolean fileValid(Context context, String path) { + + if (path == null || path.equals("")) + return true; + if (path.startsWith("content://") || path.startsWith("/content/")) { + int fd = get_fd(context, path); + if (fd <= 0) + return false; + } else { + File file = new File(path); + return file.exists(); + } + return true; + } + + public static HashMap fds = new HashMap(); + + public static int get_fd(final Context context, String path) { + int fd = 0; + if (path == null) + return 0; + + if (path.startsWith("/content") || path.startsWith("content://")) { + path = path.replaceFirst("/content", "content:"); + + try { + ParcelFileDescriptor pfd = context.getContentResolver().openFileDescriptor(Uri.parse(path), "rw"); + fd = pfd.getFd(); + fds.put(fd, pfd); + } catch (final FileNotFoundException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + new Handler(Looper.getMainLooper()).post(new Runnable() { + @Override + public void run() { + Toast.makeText(context, "Error: " + e, Toast.LENGTH_SHORT).show(); + } + }); + } + } else { + try { + File file = new File(path); + if (!file.exists()) + file.createNewFile(); + ParcelFileDescriptor pfd = ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_WRITE_ONLY); + fd = pfd.getFd(); + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + } + return fd; + } + + public static int close_fd(int fd) { + + if (FileUtils.fds.containsKey(fd)) { + ParcelFileDescriptor pfd = FileUtils.fds.get(fd); + try { + pfd.close(); + FileUtils.fds.remove(fd); + return 0; // success for Native side + } catch (IOException e) { + e.printStackTrace(); + } + + } + return -1; + } + + public static void writeToFile(String data, File file, Context context) { + try { + FileOutputStream fileOutStream = new FileOutputStream(file); + OutputStreamWriter outputWriter = new OutputStreamWriter(fileOutStream); + outputWriter.write(data); + outputWriter.close(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public static String readFromFile(Context context, File file) { + String contents = null; + try { + int length = (int) file.length(); + + byte[] bytes = new byte[length]; + + FileInputStream in = new FileInputStream(file); + try { + in.read(bytes); + } finally { + in.close(); + } + + contents = new String(bytes); + } catch (Exception e) { + UIUtils.toastLong(context, e.toString()); + return "error"; + } + return contents; + } + + public static boolean moveFile(String oldfilename, String newFolderPath, String newFilename) { + File folder = new File(newFolderPath); + if (!folder.exists()) + folder.mkdirs(); + + File oldfile = new File(oldfilename); + File newFile = new File(newFolderPath, newFilename); + + if (!newFile.exists()) + try { + newFile.createNewFile(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return oldfile.renameTo(newFile); + } + +} diff --git a/app/src/main/java/com/vectras/vm/utils/UIUtils.java b/app/src/main/java/com/vectras/vm/utils/UIUtils.java new file mode 100644 index 0000000..c0710db --- /dev/null +++ b/app/src/main/java/com/vectras/vm/utils/UIUtils.java @@ -0,0 +1,378 @@ +package com.vectras.vm.utils; + +import android.app.Activity; +import android.app.AlertDialog; +import android.content.ClipData; +import android.content.ClipboardManager; +import android.content.Context; +import android.content.DialogInterface; +import android.content.Intent; +import android.content.pm.ActivityInfo; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; +import android.graphics.Color; +import android.graphics.Point; +import android.net.Uri; +import android.os.Handler; +import android.os.Looper; +import android.text.InputType; +import android.text.Spannable; +import android.text.SpannableString; +import android.text.style.ForegroundColorSpan; +import android.util.Log; +import android.view.Display; +import android.view.Gravity; +import android.view.View; +import android.view.inputmethod.InputMethodManager; +import android.webkit.WebView; +import android.widget.ScrollView; +import android.widget.TextView; +import android.widget.Toast; +import androidx.appcompat.app.ActionBar; +import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.widget.Toolbar; + +import com.vectras.qemu.Config; +import com.vectras.qemu.MainActivityCommon; +import com.vectras.qemu.MainSettingsManager; +import com.vectras.qemu.utils.FileUtils; +import com.vectras.vm.R; +import com.vectras.vm.AppConfig; +import com.vectras.vm.logger.VectrasStatus; + +import java.io.IOException; +import java.util.Scanner; + +public class UIUtils { + + private static final String TAG = "UIUtils"; + + public static Spannable formatAndroidLog(String contents) { + + Scanner scanner = null; + Spannable formattedString = new SpannableString(contents); + if(contents.length()==0) + return formattedString; + + try { + scanner = new Scanner(contents); + int counter = 0; + ForegroundColorSpan colorSpan = null; + while (scanner.hasNextLine()) { + String line = scanner.nextLine(); + //FIXME: some devices don't have standard format for the log + if (line.startsWith("E/") || line.contains(" E ")) { + colorSpan = new ForegroundColorSpan(Color.rgb(255, 22, 22)); + } else if (line.startsWith("W/") || line.contains(" W ")) { + colorSpan = new ForegroundColorSpan(Color.rgb(22, 44, 255)); + } else { + colorSpan = null; + } + if (colorSpan!= null) { + formattedString.setSpan(colorSpan, counter, counter + line.length(), + Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); + } + counter += line.length()+1; + } + + }catch (Exception ex) { + Log.e(TAG, "Could not format vectras log: " + ex.getMessage()); + } finally { + if(scanner!=null) { + try { + scanner.close(); + } catch (Exception ex) { + if(Config.debug) + ex.printStackTrace(); + } + } + + } + return formattedString; + } + public static void toastLong(final Context activity, final String errStr) { + new Handler(Looper.getMainLooper()).post(new Runnable() { + @Override + public void run() { + + Toast toast = Toast.makeText(activity, errStr, Toast.LENGTH_LONG); + toast.show(); + VectrasStatus.logInfo("[I] "+errStr+""); + + } + }); + + } + + public static void showFileNotSupported(Activity context){ + UIAlert(context, "Error", "File path is not supported. Make sure you choose a file/directory from your internal storage or external sd card. Root and Download Directories are not supported."); + } + + + public static boolean onKeyboard(Activity activity, boolean toggle, View view) { + // Prevent crashes from activating mouse when machine is paused + if (MainActivityCommon.vmexecutor.paused == 1) + return !toggle; + + InputMethodManager inputMgr = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE); + + //XXX: we need to get the focused view to make this always work + //inputMgr.toggleSoftInput(0, 0); + + +// View view = activity.getCurrentFocus(); + if (toggle || !Config.enableToggleKeyboard){ + if(view!=null) { + view.requestFocus(); + inputMgr.showSoftInput(view, InputMethodManager.SHOW_FORCED); + } + } else { + if (view != null) { + inputMgr.hideSoftInputFromWindow(view.getWindowToken(), 0); + } + } + + return !toggle; + } + + public static void hideKeyboard(Activity activity, View view) { + InputMethodManager inputMgr = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE); + if (view != null) { + inputMgr.hideSoftInputFromWindow(view.getWindowToken(), 0); + } + } + + public static void toastShortTop(final Activity activity, final String errStr) { + UIUtils.toast(activity, errStr, Gravity.TOP | Gravity.CENTER, Toast.LENGTH_SHORT); + } + + public static void toast(final Context context, final String errStr, final int gravity, final int length) { + new Handler(Looper.getMainLooper()).post(new Runnable() { + @Override + public void run() { + if(context instanceof Activity && ((Activity) context).isFinishing()) { + return ; + } + Toast toast = Toast.makeText(context, errStr, length); + toast.setGravity(gravity, 0, 0); + toast.show(); + + } + }); + + } + + public static void toastShort(final Context context, final String errStr) { + toast(context, errStr, Gravity.CENTER | Gravity.CENTER, Toast.LENGTH_SHORT); + + } + + public static void setOrientation(Activity activity) { + int orientation = MainSettingsManager.getOrientationSetting(activity); + switch (orientation) { + case 0: + activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED); + break; + case 1: + activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); + break; + case 2: + activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE); + break; + case 3: + activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); + break; + case 4: + activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT); + break; + } + } + + + public static void onChangeLog(Activity activity) { + PackageInfo pInfo = null; + + try { + pInfo = activity.getPackageManager().getPackageInfo(activity.getClass().getPackage().getName(), + PackageManager.GET_META_DATA); + } catch (PackageManager.NameNotFoundException e) { + e.printStackTrace(); + } + com.vectras.qemu.utils.FileUtils fileutils = new com.vectras.qemu.utils.FileUtils(); + try { + UIUtils.UIAlert(activity,"CHANGELOG", fileutils.LoadFile(activity, "CHANGELOG", false), + 0, false, "OK", null, null, null, null, null); + } catch (IOException e) { + + e.printStackTrace(); + } + } + + + + public static void showHints(Activity activity) { + + + UIUtils.toastShortTop(activity, "Press Volume Down for Right Click"); + + + } + + public static boolean isLandscapeOrientation(Activity activity) + { + Display display = activity.getWindowManager().getDefaultDisplay(); + Point screenSize = new Point(); + display.getSize(screenSize); + if(screenSize.x < screenSize.y) + return false; + return true; + } + + private static void openURL(Activity activity, String url) { + try { + Intent fileIntent = new Intent(Intent.ACTION_VIEW); + fileIntent.setData(Uri.parse(url)); + activity.startActivity(fileIntent); + }catch (Exception ex) { + UIUtils.toastShort(activity, "Could not open url"); + } + } + + public static void UIAlert(Activity activity, String title, String body) { + + AlertDialog alertDialog; + alertDialog = new AlertDialog.Builder(activity, R.style.MainDialogTheme).create(); + alertDialog.setTitle(title); + TextView textView = new TextView(activity); + textView.setPadding(20,20,20,20); + textView.setText(body); + ScrollView view = new ScrollView(activity); + view.addView(textView); + alertDialog.setView(view); + alertDialog.setButton(DialogInterface.BUTTON_POSITIVE, "OK", new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int which) { + return; + } + }); + alertDialog.show(); + } + + public static void UIAlert(Activity activity, String title, String body, int textSize, boolean cancelable, + String button1title, DialogInterface.OnClickListener button1Listener, + String button2title, DialogInterface.OnClickListener button2Listener, + String button3title, DialogInterface.OnClickListener button3Listener + ) { + + AlertDialog alertDialog; + alertDialog = new AlertDialog.Builder(activity, R.style.MainDialogTheme).create(); + alertDialog.setTitle(title); + alertDialog.setCanceledOnTouchOutside(cancelable); + TextView textView = new TextView(activity); + textView.setPadding(20,20,20,20); + textView.setText(body); + if(textSize>0) + textView.setTextSize(textSize); + textView.setBackgroundColor(Color.WHITE); + textView.setTextColor(Color.BLACK); + ScrollView view = new ScrollView(activity); + view.addView(textView); + alertDialog.setView(view); + if(button1title!=null) + alertDialog.setButton(AlertDialog.BUTTON_POSITIVE, button1title, button1Listener); + if(button2title!=null) + alertDialog.setButton(AlertDialog.BUTTON_NEGATIVE, button2title, button2Listener); + if(button3title!=null) + alertDialog.setButton(AlertDialog.BUTTON_NEUTRAL, button3title, button3Listener); + alertDialog.show(); + } + + public static void UIAlertLog(final Activity activity, String title, Spannable body) { + + AlertDialog alertDialog; + alertDialog = new AlertDialog.Builder(activity, R.style.MainDialogTheme).create(); + alertDialog.setTitle(title); + TextView textView = new TextView(activity); + textView.setPadding(20,20,20,20); + textView.setText(body); + textView.setBackgroundColor(Color.BLACK); + textView.setTextSize(12); + textView.setInputType(InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS); + textView.setSingleLine(false); + ScrollView view = new ScrollView(activity); + view.addView(textView); + alertDialog.setView(view); + alertDialog.setCanceledOnTouchOutside(false); + alertDialog.setButton(DialogInterface.BUTTON_POSITIVE, "OK", new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int which) { + return; + } + }); + alertDialog.setButton(DialogInterface.BUTTON_NEUTRAL, "Copy To", new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int which) { + ClipboardManager clipboardManager = (ClipboardManager) + activity.getSystemService(Context.CLIPBOARD_SERVICE); + ClipData clipData = ClipData.newPlainText("nonsense_data", + body); + clipboardManager.setPrimaryClip(clipData); + UIUtils.toastShort(activity, "Copied to clipboard successfully!"); + return; + } + }); + alertDialog.show(); + } + + public static void UIAlertHtml(String title, String body, Activity activity) { + + AlertDialog alertDialog; + alertDialog = new AlertDialog.Builder(activity, R.style.MainDialogTheme).create(); + alertDialog.setTitle(title); + + try { + WebView webview = new WebView(activity); + webview.loadData(body, "text/html", "UTF-8"); + alertDialog.setView(webview); + } catch (Exception ex) { + TextView textView = new TextView(activity); + textView.setText(body); + alertDialog.setView(textView); + } + + alertDialog.setButton(DialogInterface.BUTTON_POSITIVE, "OK", new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int which) { + return; + } + }); + alertDialog.show(); + } + + public static void promptShowLog(final Activity activity) { + + final AlertDialog alertDialog; + alertDialog = new AlertDialog.Builder(activity, R.style.MainDialogTheme).create(); + alertDialog.setTitle("Show log"); + TextView stateView = new TextView(activity); + stateView.setText("Something happened during last run, do you want to see the log?"); + stateView.setPadding(20, 20, 20, 20); + alertDialog.setView(stateView); + + // alertDialog.setMessage(body); + alertDialog.setButton(DialogInterface.BUTTON_POSITIVE, "Yes", + new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int which) { + + FileUtils.viewVectrasLog(activity); + } + }); + alertDialog.setButton(DialogInterface.BUTTON_NEGATIVE, "Cancel", + new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int which) { + + + } + }); + alertDialog.show(); + + } + + +} diff --git a/app/src/main/java/com/vectras/vm/widgets/JoystickView.java b/app/src/main/java/com/vectras/vm/widgets/JoystickView.java new file mode 100644 index 0000000..4c3e164 --- /dev/null +++ b/app/src/main/java/com/vectras/vm/widgets/JoystickView.java @@ -0,0 +1,873 @@ +package com.vectras.vm.widgets; + + +import android.content.Context; +import android.content.res.TypedArray; +import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.Paint; +import android.graphics.drawable.BitmapDrawable; +import android.graphics.drawable.Drawable; +import android.os.Handler; +import android.util.AttributeSet; +import android.view.MotionEvent; +import android.view.View; +import android.view.ViewConfiguration; + +import com.vectras.vm.R; + +public class JoystickView extends View + implements + Runnable { + + + /* + INTERFACES + */ + + + /** + * Interface definition for a callback to be invoked when a + * JoystickView's button is moved + */ + public interface OnMoveListener { + + /** + * Called when a JoystickView's button has been moved + * @param angle current angle + * @param strength current strength + */ + void onMove(int angle, int strength); + } + + + /** + * Interface definition for a callback to be invoked when a JoystickView + * is touched and held by multiple pointers. + */ + public interface OnMultipleLongPressListener { + /** + * Called when a JoystickView has been touch and held enough time by multiple pointers. + */ + void onMultipleLongPress(); + } + + + /* + CONSTANTS + */ + + /** + * Default refresh rate as a time in milliseconds to send move values through callback + */ + private static final int DEFAULT_LOOP_INTERVAL = 50; // in milliseconds + + /** + * Used to allow a slight move without cancelling MultipleLongPress + */ + private static final int MOVE_TOLERANCE = 10; + + /** + * Default color for button + */ + private static final int DEFAULT_COLOR_BUTTON = Color.BLACK; + + /** + * Default color for border + */ + private static final int DEFAULT_COLOR_BORDER = Color.TRANSPARENT; + + /** + * Default alpha for border + */ + private static final int DEFAULT_ALPHA_BORDER = 255; + + /** + * Default background color + */ + private static final int DEFAULT_BACKGROUND_COLOR = Color.TRANSPARENT; + + /** + * Default View's size + */ + private static final int DEFAULT_SIZE = 200; + + /** + * Default border's width + */ + private static final int DEFAULT_WIDTH_BORDER = 3; + + /** + * Default behavior to fixed center (not auto-defined) + */ + private static final boolean DEFAULT_FIXED_CENTER = true; + + + /** + * Default behavior to auto re-center button (automatically recenter the button) + */ + private static final boolean DEFAULT_AUTO_RECENTER_BUTTON = true; + + + /** + * Default behavior to button stickToBorder (button stay on the border) + */ + private static final boolean DEFAULT_BUTTON_STICK_TO_BORDER = false; + + + // DRAWING + private Paint mPaintCircleButton; + private Paint mPaintCircleBorder; + private Paint mPaintBackground; + + private Paint mPaintBitmapButton; + private Bitmap mButtonBitmap; + + + /** + * Ratio use to define the size of the button + */ + private float mButtonSizeRatio; + + + /** + * Ratio use to define the size of the background + * + */ + private float mBackgroundSizeRatio; + + + // COORDINATE + private int mPosX = 0; + private int mPosY = 0; + private int mCenterX = 0; + private int mCenterY = 0; + + private int mFixedCenterX = 0; + private int mFixedCenterY = 0; + + /** + * Used to adapt behavior whether it is auto-defined center (false) or fixed center (true) + */ + private boolean mFixedCenter; + + + /** + * Used to adapt behavior whether the button is automatically re-centered (true) + * when released or not (false) + */ + private boolean mAutoReCenterButton; + + + /** + * Used to adapt behavior whether the button is stick to border (true) or + * could be anywhere (when false - similar to regular behavior) + */ + private boolean mButtonStickToBorder; + + + /** + * Used to enabled/disabled the Joystick. When disabled (enabled to false) the joystick button + * can't move and onMove is not called. + */ + private boolean mEnabled; + + + // SIZE + private int mButtonRadius; + private int mBorderRadius; + + + /** + * Alpha of the border (to use when changing color dynamically) + */ + private int mBorderAlpha; + + + /** + * Based on mBorderRadius but a bit smaller (minus half the stroke size of the border) + */ + private float mBackgroundRadius; + + + /** + * Listener used to dispatch OnMove event + */ + private OnMoveListener mCallback; + + private long mLoopInterval = DEFAULT_LOOP_INTERVAL; + private Thread mThread = new Thread(this); + + + /** + * Listener used to dispatch MultipleLongPress event + */ + private OnMultipleLongPressListener mOnMultipleLongPressListener; + + private final Handler mHandlerMultipleLongPress = new Handler(); + private Runnable mRunnableMultipleLongPress; + private int mMoveTolerance; + + + /** + * Default value. + * Both direction correspond to horizontal and vertical movement + */ + public static int BUTTON_DIRECTION_BOTH = 0; + + /** + * The allowed direction of the button is define by the value of this parameter: + * - a negative value for horizontal axe + * - a positive value for vertical axe + * - zero for both axes + */ + private int mButtonDirection = 0; + + + /* + CONSTRUCTORS + */ + + + /** + * Simple constructor to use when creating a JoystickView from code. + * Call another constructor passing null to Attribute. + * @param context The Context the JoystickView is running in, through which it can + * access the current theme, resources, etc. + */ + public JoystickView(Context context) { + this(context, null); + } + + + public JoystickView(Context context, AttributeSet attrs, int defStyleAttr) { + this(context, attrs); + } + + + /** + * Constructor that is called when inflating a JoystickView from XML. This is called + * when a JoystickView is being constructed from an XML file, supplying attributes + * that were specified in the XML file. + * @param context The Context the JoystickView is running in, through which it can + * access the current theme, resources, etc. + * @param attrs The attributes of the XML tag that is inflating the JoystickView. + */ + public JoystickView(Context context, AttributeSet attrs) { + super(context, attrs); + + TypedArray styledAttributes = context.getTheme().obtainStyledAttributes( + attrs, + R.styleable.JoystickView, + 0, 0 + ); + + int buttonColor; + int borderColor; + int backgroundColor; + int borderWidth; + Drawable buttonDrawable; + try { + buttonColor = styledAttributes.getColor(R.styleable.JoystickView_JV_buttonColor, DEFAULT_COLOR_BUTTON); + borderColor = styledAttributes.getColor(R.styleable.JoystickView_JV_borderColor, DEFAULT_COLOR_BORDER); + mBorderAlpha = styledAttributes.getInt(R.styleable.JoystickView_JV_borderAlpha, DEFAULT_ALPHA_BORDER); + backgroundColor = styledAttributes.getColor(R.styleable.JoystickView_JV_backgroundColor, DEFAULT_BACKGROUND_COLOR); + borderWidth = styledAttributes.getDimensionPixelSize(R.styleable.JoystickView_JV_borderWidth, DEFAULT_WIDTH_BORDER); + mFixedCenter = styledAttributes.getBoolean(R.styleable.JoystickView_JV_fixedCenter, DEFAULT_FIXED_CENTER); + mAutoReCenterButton = styledAttributes.getBoolean(R.styleable.JoystickView_JV_autoReCenterButton, DEFAULT_AUTO_RECENTER_BUTTON); + mButtonStickToBorder = styledAttributes.getBoolean(R.styleable.JoystickView_JV_buttonStickToBorder, DEFAULT_BUTTON_STICK_TO_BORDER); + buttonDrawable = styledAttributes.getDrawable(R.styleable.JoystickView_JV_buttonImage); + mEnabled = styledAttributes.getBoolean(R.styleable.JoystickView_JV_enabled, true); + mButtonSizeRatio = styledAttributes.getFraction(R.styleable.JoystickView_JV_buttonSizeRatio, 1, 1, 0.25f); + mBackgroundSizeRatio = styledAttributes.getFraction(R.styleable.JoystickView_JV_backgroundSizeRatio, 1, 1, 0.75f); + mButtonDirection = styledAttributes.getInteger(R.styleable.JoystickView_JV_buttonDirection, BUTTON_DIRECTION_BOTH); + } finally { + styledAttributes.recycle(); + } + + // Initialize the drawing according to attributes + + mPaintCircleButton = new Paint(); + mPaintCircleButton.setAntiAlias(true); + mPaintCircleButton.setColor(buttonColor); + mPaintCircleButton.setStyle(Paint.Style.FILL); + + if (buttonDrawable != null) { + if (buttonDrawable instanceof BitmapDrawable) { + mButtonBitmap = ((BitmapDrawable) buttonDrawable).getBitmap(); + mPaintBitmapButton = new Paint(); + } + } + + mPaintCircleBorder = new Paint(); + mPaintCircleBorder.setAntiAlias(true); + mPaintCircleBorder.setColor(borderColor); + mPaintCircleBorder.setStyle(Paint.Style.STROKE); + mPaintCircleBorder.setStrokeWidth(borderWidth); + + if (borderColor != Color.TRANSPARENT) { + mPaintCircleBorder.setAlpha(mBorderAlpha); + } + + mPaintBackground = new Paint(); + mPaintBackground.setAntiAlias(true); + mPaintBackground.setColor(backgroundColor); + mPaintBackground.setStyle(Paint.Style.FILL); + + + // Init Runnable for MultiLongPress + + mRunnableMultipleLongPress = new Runnable() { + @Override + public void run() { + if (mOnMultipleLongPressListener != null) + mOnMultipleLongPressListener.onMultipleLongPress(); + } + }; + } + + + private void initPosition() { + // get the center of view to position circle + mFixedCenterX = mCenterX = mPosX = getWidth() / 2; + mFixedCenterY = mCenterY = mPosY = getWidth() / 2; + } + + + /** + * Draw the background, the border and the button + * @param canvas the canvas on which the shapes will be drawn + */ + @Override + protected void onDraw(Canvas canvas) { + // Draw the background + canvas.drawCircle(mFixedCenterX, mFixedCenterY, mBackgroundRadius, mPaintBackground); + + // Draw the circle border + canvas.drawCircle(mFixedCenterX, mFixedCenterY, mBorderRadius, mPaintCircleBorder); + + // Draw the button from image + if (mButtonBitmap != null) { + canvas.drawBitmap( + mButtonBitmap, + mPosX + mFixedCenterX - mCenterX - mButtonRadius, + mPosY + mFixedCenterY - mCenterY - mButtonRadius, + mPaintBitmapButton + ); + } + // Draw the button as simple circle + else { + canvas.drawCircle( + mPosX + mFixedCenterX - mCenterX, + mPosY + mFixedCenterY - mCenterY, + mButtonRadius, + mPaintCircleButton + ); + } + } + + + /** + * This is called during layout when the size of this view has changed. + * Here we get the center of the view and the radius to draw all the shapes. + * + * @param w Current width of this view. + * @param h Current height of this view. + * @param oldW Old width of this view. + * @param oldH Old height of this view. + */ + @Override + protected void onSizeChanged(int w, int h, int oldW, int oldH) { + super.onSizeChanged(w, h, oldW, oldH); + + initPosition(); + + // radius based on smallest size : height OR width + int d = Math.min(w, h); + mButtonRadius = (int) (d / 2 * mButtonSizeRatio); + mBorderRadius = (int) (d / 2 * mBackgroundSizeRatio); + mBackgroundRadius = mBorderRadius - (mPaintCircleBorder.getStrokeWidth() / 2); + + if (mButtonBitmap != null) + mButtonBitmap = Bitmap.createScaledBitmap(mButtonBitmap, mButtonRadius * 2, mButtonRadius * 2, true); + } + + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + // setting the measured values to resize the view to a certain width and height + int d = Math.min(measure(widthMeasureSpec), measure(heightMeasureSpec)); + setMeasuredDimension(d, d); + } + + + private int measure(int measureSpec) { + if (MeasureSpec.getMode(measureSpec) == MeasureSpec.UNSPECIFIED) { + // if no bounds are specified return a default size (200) + return DEFAULT_SIZE; + } else { + // As you want to fill the available space + // always return the full available bounds. + return MeasureSpec.getSize(measureSpec); + } + } + + + /* + USER EVENT + */ + + + /** + * Handle touch screen motion event. Move the button according to the + * finger coordinate and detect longPress by multiple pointers only. + * + * @param event The motion event. + * @return True if the event was handled, false otherwise. + */ + @Override + public boolean onTouchEvent(MotionEvent event) { + // if disabled we don't move the + if (!mEnabled) { + return true; + } + + + // to move the button according to the finger coordinate + // (or limited to one axe according to direction option + mPosY = mButtonDirection < 0 ? mCenterY : (int) event.getY(); // direction negative is horizontal axe + mPosX = mButtonDirection > 0 ? mCenterX : (int) event.getX(); // direction positive is vertical axe + + if (event.getAction() == MotionEvent.ACTION_UP) { + + // stop listener because the finger left the touch screen + mThread.interrupt(); + + // re-center the button or not (depending on settings) + if (mAutoReCenterButton) { + resetButtonPosition(); + + // update now the last strength and angle which should be zero after resetButton + if (mCallback != null) + mCallback.onMove(getAngle(), getStrength()); + } + + // if mAutoReCenterButton is false we will send the last strength and angle a bit + // later only after processing new position X and Y otherwise it could be above the border limit + } + + if (event.getAction() == MotionEvent.ACTION_DOWN) { + if (mThread != null && mThread.isAlive()) { + mThread.interrupt(); + } + + mThread = new Thread(this); + mThread.start(); + + if (mCallback != null) + mCallback.onMove(getAngle(), getStrength()); + } + + // handle first touch and long press with multiple touch only + switch (event.getActionMasked()) { + case MotionEvent.ACTION_DOWN: + // when the first touch occurs we update the center (if set to auto-defined center) + if (!mFixedCenter) { + mCenterX = mPosX; + mCenterY = mPosY; + } + break; + + case MotionEvent.ACTION_POINTER_DOWN: { + // when the second finger touch + if (event.getPointerCount() == 2) { + mHandlerMultipleLongPress.postDelayed(mRunnableMultipleLongPress, ViewConfiguration.getLongPressTimeout()*2); + mMoveTolerance = MOVE_TOLERANCE; + } + break; + } + + case MotionEvent.ACTION_MOVE: + mMoveTolerance--; + if (mMoveTolerance == 0) { + mHandlerMultipleLongPress.removeCallbacks(mRunnableMultipleLongPress); + } + break; + + case MotionEvent.ACTION_POINTER_UP: { + // when the last multiple touch is released + if (event.getPointerCount() == 2) { + mHandlerMultipleLongPress.removeCallbacks(mRunnableMultipleLongPress); + } + break; + } + } + + double abs = Math.sqrt((mPosX - mCenterX) * (mPosX - mCenterX) + + (mPosY - mCenterY) * (mPosY - mCenterY)); + + // (abs > mBorderRadius) means button is too far therefore we limit to border + // (buttonStickBorder && abs != 0) means wherever is the button we stick it to the border except when abs == 0 + if (abs > mBorderRadius || (mButtonStickToBorder && abs != 0)) { + mPosX = (int) ((mPosX - mCenterX) * mBorderRadius / abs + mCenterX); + mPosY = (int) ((mPosY - mCenterY) * mBorderRadius / abs + mCenterY); + } + + if (!mAutoReCenterButton) { + // Now update the last strength and angle if not reset to center + if (mCallback != null) + mCallback.onMove(getAngle(), getStrength()); + } + + + // to force a new draw + invalidate(); + + return true; + } + + + /* + GETTERS + */ + + + /** + * Process the angle following the 360° counter-clock protractor rules. + * @return the angle of the button + */ + private int getAngle() { + int angle = (int) Math.toDegrees(Math.atan2(mCenterY - mPosY, mPosX - mCenterX)); + return angle < 0 ? angle + 360 : angle; // make it as a regular counter-clock protractor + } + + + /** + * Process the strength as a percentage of the distance between the center and the border. + * @return the strength of the button + */ + private int getStrength() { + return (int) (100 * Math.sqrt((mPosX - mCenterX) + * (mPosX - mCenterX) + (mPosY - mCenterY) + * (mPosY - mCenterY)) / mBorderRadius); + } + + + /** + * Reset the button position to the center. + */ + public void resetButtonPosition() { + mPosX = mCenterX; + mPosY = mCenterY; + } + + + /** + * Return the current direction allowed for the button to move + * @return Actually return an integer corresponding to the direction: + * - A negative value is horizontal axe, + * - A positive value is vertical axe, + * - Zero means both axes + */ + public int getButtonDirection() { + return mButtonDirection; + } + + + /** + * Return the state of the joystick. False when the button don't move. + * @return the state of the joystick + */ + public boolean isEnabled() { + return mEnabled; + } + + + /** + * Return the size of the button (as a ratio of the total width/height) + * Default is 0.25 (25%). + * @return button size (value between 0.0 and 1.0) + */ + public float getButtonSizeRatio() { + return mButtonSizeRatio; + } + + + /** + * Return the size of the background (as a ratio of the total width/height) + * Default is 0.75 (75%). + * @return background size (value between 0.0 and 1.0) + */ + public float getmBackgroundSizeRatio() { + return mBackgroundSizeRatio; + } + + + /** + * Return the current behavior of the auto re-center button + * @return True if automatically re-centered or False if not + */ + public boolean isAutoReCenterButton() { + return mAutoReCenterButton; + } + + + /** + * Return the current behavior of the button stick to border + * @return True if the button stick to the border otherwise False + */ + public boolean isButtonStickToBorder() { + return mButtonStickToBorder; + } + + + /** + * Return the relative X coordinate of button center related + * to top-left virtual corner of the border + * @return coordinate of X (normalized between 0 and 100) + */ + public int getNormalizedX() { + if (getWidth() == 0) { + return 50; + } + return Math.round((mPosX-mButtonRadius)*100.0f/(getWidth()-mButtonRadius*2)); + } + + + /** + * Return the relative Y coordinate of the button center related + * to top-left virtual corner of the border + * @return coordinate of Y (normalized between 0 and 100) + */ + public int getNormalizedY() { + if (getHeight() == 0) { + return 50; + } + return Math.round((mPosY-mButtonRadius)*100.0f/(getHeight()-mButtonRadius*2)); + } + + + /** + * Return the alpha of the border + * @return it should be an integer between 0 and 255 previously set + */ + public int getBorderAlpha() { + return mBorderAlpha; + } + + /* + SETTERS + */ + + + /** + * Set an image to the button with a drawable + * @param d drawable to pick the image + */ + public void setButtonDrawable(Drawable d) { + if (d != null) { + if (d instanceof BitmapDrawable) { + mButtonBitmap = ((BitmapDrawable) d).getBitmap(); + + if (mButtonRadius != 0) { + mButtonBitmap = Bitmap.createScaledBitmap( + mButtonBitmap, + mButtonRadius * 2, + mButtonRadius * 2, + true); + } + + if (mPaintBitmapButton != null) + mPaintBitmapButton = new Paint(); + } + } + } + + + /** + * Set the button color for this JoystickView. + * @param color the color of the button + */ + public void setButtonColor(int color) { + mPaintCircleButton.setColor(color); + invalidate(); + } + + + /** + * Set the border color for this JoystickView. + * @param color the color of the border + */ + public void setBorderColor(int color) { + mPaintCircleBorder.setColor(color); + if (color != Color.TRANSPARENT) { + mPaintCircleBorder.setAlpha(mBorderAlpha); + } + invalidate(); + } + + + /** + * Set the border alpha for this JoystickView. + * @param alpha the transparency of the border between 0 and 255 + */ + public void setBorderAlpha(int alpha) { + mBorderAlpha = alpha; + mPaintCircleBorder.setAlpha(alpha); + invalidate(); + } + + + /** + * Set the background color for this JoystickView. + * @param color the color of the background + */ + @Override + public void setBackgroundColor(int color) { + mPaintBackground.setColor(color); + invalidate(); + } + + + /** + * Set the border width for this JoystickView. + * @param width the width of the border + */ + public void setBorderWidth(int width) { + mPaintCircleBorder.setStrokeWidth(width); + mBackgroundRadius = mBorderRadius - (width / 2.0f); + invalidate(); + } + + + /** + * Register a callback to be invoked when this JoystickView's button is moved + * @param l The callback that will run + */ + public void setOnMoveListener(OnMoveListener l) { + setOnMoveListener(l, DEFAULT_LOOP_INTERVAL); + } + + + /** + * Register a callback to be invoked when this JoystickView's button is moved + * @param l The callback that will run + * @param loopInterval Refresh rate to be invoked in milliseconds + */ + public void setOnMoveListener(OnMoveListener l, int loopInterval) { + mCallback = l; + mLoopInterval = loopInterval; + } + + + /** + * Register a callback to be invoked when this JoystickView is touch and held by multiple pointers + * @param l The callback that will run + */ + public void setOnMultiLongPressListener(OnMultipleLongPressListener l) { + mOnMultipleLongPressListener = l; + } + + + /** + * Set the joystick center's behavior (fixed or auto-defined) + * @param fixedCenter True for fixed center, False for auto-defined center based on touch down + */ + public void setFixedCenter(boolean fixedCenter) { + // if we set to "fixed" we make sure to re-init position related to the width of the joystick + if (fixedCenter) { + initPosition(); + } + mFixedCenter = fixedCenter; + invalidate(); + } + + + /** + * Enable or disable the joystick + * @param enabled False mean the button won't move and onMove won't be called + */ + public void setEnabled(boolean enabled) { + mEnabled = enabled; + } + + + /** + * Set the joystick button size (as a fraction of the real width/height) + * By default it is 25% (0.25). + * @param newRatio between 0.0 and 1.0 + */ + public void setButtonSizeRatio(float newRatio) { + if (newRatio > 0.0f & newRatio <= 1.0f) { + mButtonSizeRatio = newRatio; + } + } + + + /** + * Set the joystick button size (as a fraction of the real width/height) + * By default it is 75% (0.75). + * Not working if the background is an image. + * @param newRatio between 0.0 and 1.0 + */ + public void setBackgroundSizeRatio(float newRatio) { + if (newRatio > 0.0f & newRatio <= 1.0f) { + mBackgroundSizeRatio = newRatio; + } + } + + + /** + * Set the current behavior of the auto re-center button + * @param b True if automatically re-centered or False if not + */ + public void setAutoReCenterButton(boolean b) { + mAutoReCenterButton = b; + } + + + /** + * Set the current behavior of the button stick to border + * @param b True if the button stick to the border or False (default) if not + */ + public void setButtonStickToBorder(boolean b) { + mButtonStickToBorder = b; + } + + + /** + * Set the current authorized direction for the button to move + * @param direction the value will define the authorized direction: + * - any negative value (such as -1) for horizontal axe + * - any positive value (such as 1) for vertical axe + * - zero (0) for the full direction (both axes) + */ + public void setButtonDirection(int direction) { + mButtonDirection = direction; + } + + + /* + IMPLEMENTS + */ + + + @Override // Runnable + public void run() { + while (!Thread.interrupted()) { + post(new Runnable() { + public void run() { + if (mCallback != null) + mCallback.onMove(getAngle(), getStrength()); + } + }); + + try { + Thread.sleep(mLoopInterval); + } catch (InterruptedException e) { + break; + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/vectras/vm/widgets/RadioGroupPlus.java b/app/src/main/java/com/vectras/vm/widgets/RadioGroupPlus.java new file mode 100644 index 0000000..5b326b4 --- /dev/null +++ b/app/src/main/java/com/vectras/vm/widgets/RadioGroupPlus.java @@ -0,0 +1,370 @@ +package com.vectras.vm.widgets; + +import android.content.Context; +import android.content.res.TypedArray; +import android.util.AttributeSet; +import android.view.View; +import android.view.ViewGroup; +import android.widget.CompoundButton; +import android.widget.LinearLayout; +import android.widget.RadioButton; +import android.widget.RadioGroup; +import androidx.annotation.IdRes; + +public class RadioGroupPlus extends LinearLayout { + // holds the checked id; the selection is empty by default + private int mCheckedId = -1; + // tracks children radio buttons checked state + private CompoundButton.OnCheckedChangeListener mChildOnCheckedChangeListener; + // when true, mOnCheckedChangeListener discards events + private boolean mProtectFromCheckedChange = false; + private OnCheckedChangeListener mOnCheckedChangeListener; + private PassThroughHierarchyChangeListener mPassThroughListener; + + /** + * {@inheritDoc} + */ + public RadioGroupPlus(Context context) { + super(context); + setOrientation(VERTICAL); + init(); + } + + /** + * {@inheritDoc} + */ + public RadioGroupPlus(Context context, AttributeSet attrs) { + super(context, attrs); + + // retrieve selected radio button as requested by the user in the + // XML layout file + //TODO: fix ignored attributes +// TypedArray attributes = context.obtainStyledAttributes( +// attrs, com.android.internal.R.styleable.RadioGroup, com.android.internal.R.attr.radioButtonStyle, 0); + +// int value = attributes.getResourceId(com.android.internal.R.styleable.RadioGroup_checkedButton, View.NO_ID); +// if (value != View.NO_ID) { +// mCheckedId = value; +// } + +// final int index = attributes.getInt(com.android.internal.R.styleable.RadioGroup_orientation, VERTICAL); +// setOrientation(index); + +// attributes.recycle(); + init(); + } + + private void init() { + mChildOnCheckedChangeListener = new CheckedStateTracker(); + mPassThroughListener = new PassThroughHierarchyChangeListener(); + super.setOnHierarchyChangeListener(mPassThroughListener); + } + + /** + * {@inheritDoc} + */ + @Override + public void setOnHierarchyChangeListener(OnHierarchyChangeListener listener) { + // the user listener is delegated to our pass-through listener + mPassThroughListener.mOnHierarchyChangeListener = listener; + } + + /** + * {@inheritDoc} + */ + @Override + protected void onFinishInflate() { + super.onFinishInflate(); + + // checks the appropriate radio button as requested in the XML file + if (mCheckedId != -1) { + mProtectFromCheckedChange = true; + setCheckedStateForView(mCheckedId, true); + mProtectFromCheckedChange = false; + setCheckedId(mCheckedId); + } + } + + @Override + public void addView(View child, int index, ViewGroup.LayoutParams params) { + if (child instanceof RadioButton) { + final RadioButton button = (RadioButton) child; + if (button.isChecked()) { + mProtectFromCheckedChange = true; + if (mCheckedId != -1) { + setCheckedStateForView(mCheckedId, false); + } + mProtectFromCheckedChange = false; + setCheckedId(button.getId()); + } + } + + super.addView(child, index, params); + } + + /** + *

Sets the selection to the radio button whose identifier is passed in + * parameter. Using -1 as the selection identifier clears the selection; + * such an operation is equivalent to invoking {@link #clearCheck()}.

+ * + * @param id the unique id of the radio button to select in this group + * @see #getCheckedRadioButtonId() + * @see #clearCheck() + */ + public void check(@IdRes int id) { + // don't even bother + if (id != -1 && (id == mCheckedId)) { + return; + } + + if (mCheckedId != -1) { + setCheckedStateForView(mCheckedId, false); + } + + if (id != -1) { + setCheckedStateForView(id, true); + } + + setCheckedId(id); + } + + private void setCheckedId(@IdRes int id) { + mCheckedId = id; + if (mOnCheckedChangeListener != null) { + mOnCheckedChangeListener.onCheckedChanged(this, mCheckedId); + } + } + + private void setCheckedStateForView(int viewId, boolean checked) { + View checkedView = findViewById(viewId); + if (checkedView != null && checkedView instanceof RadioButton) { + ((RadioButton) checkedView).setChecked(checked); + } + } + + /** + *

Returns the identifier of the selected radio button in this group. + * Upon empty selection, the returned value is -1.

+ * + * @return the unique id of the selected radio button in this group + * @attr ref android.R.styleable#RadioGroup_checkedButton + * @see #check(int) + * @see #clearCheck() + */ + @IdRes + public int getCheckedRadioButtonId() { + return mCheckedId; + } + + /** + *

Clears the selection. When the selection is cleared, no radio button + * in this group is selected and {@link #getCheckedRadioButtonId()} returns + * null.

+ * + * @see #check(int) + * @see #getCheckedRadioButtonId() + */ + public void clearCheck() { + check(-1); + } + + /** + *

Register a callback to be invoked when the checked radio button + * changes in this group.

+ * + * @param listener the callback to call on checked state change + */ + public void setOnCheckedChangeListener(OnCheckedChangeListener listener) { + mOnCheckedChangeListener = listener; + } + + /** + * {@inheritDoc} + */ + @Override + public LayoutParams generateLayoutParams(AttributeSet attrs) { + return new RadioGroupPlus.LayoutParams(getContext(), attrs); + } + + /** + * {@inheritDoc} + */ + @Override + protected boolean checkLayoutParams(ViewGroup.LayoutParams p) { + return p instanceof RadioGroup.LayoutParams; + } + + @Override + protected LinearLayout.LayoutParams generateDefaultLayoutParams() { + return new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); + } + + @Override + public CharSequence getAccessibilityClassName() { + return RadioGroup.class.getName(); + } + + public static class LayoutParams extends LinearLayout.LayoutParams { + /** + * {@inheritDoc} + */ + public LayoutParams(Context c, AttributeSet attrs) { + super(c, attrs); + } + + /** + * {@inheritDoc} + */ + public LayoutParams(int w, int h) { + super(w, h); + } + + /** + * {@inheritDoc} + */ + public LayoutParams(int w, int h, float initWeight) { + super(w, h, initWeight); + } + + /** + * {@inheritDoc} + */ + public LayoutParams(ViewGroup.LayoutParams p) { + super(p); + } + + /** + * {@inheritDoc} + */ + public LayoutParams(MarginLayoutParams source) { + super(source); + } + + /** + *

Fixes the child's width to + * {@link android.view.ViewGroup.LayoutParams#WRAP_CONTENT} and the child's + * height to {@link android.view.ViewGroup.LayoutParams#WRAP_CONTENT} + * when not specified in the XML file.

+ * + * @param a the styled attributes set + * @param widthAttr the width attribute to fetch + * @param heightAttr the height attribute to fetch + */ + @Override + protected void setBaseAttributes(TypedArray a, + int widthAttr, int heightAttr) { + + if (a.hasValue(widthAttr)) { + width = a.getLayoutDimension(widthAttr, "layout_width"); + } else { + width = WRAP_CONTENT; + } + + if (a.hasValue(heightAttr)) { + height = a.getLayoutDimension(heightAttr, "layout_height"); + } else { + height = WRAP_CONTENT; + } + } + } + + /** + *

Interface definition for a callback to be invoked when the checked + * radio button changed in this group.

+ */ + public interface OnCheckedChangeListener { + /** + *

Called when the checked radio button has changed. When the + * selection is cleared, checkedId is -1.

+ * + * @param group the group in which the checked radio button has changed + * @param checkedId the unique identifier of the newly checked radio button + */ + public void onCheckedChanged(RadioGroupPlus group, @IdRes int checkedId); + } + + private class CheckedStateTracker implements CompoundButton.OnCheckedChangeListener { + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + // prevents from infinite recursion + if (mProtectFromCheckedChange) { + return; + } + + mProtectFromCheckedChange = true; + if (mCheckedId != -1) { + setCheckedStateForView(mCheckedId, false); + } + mProtectFromCheckedChange = false; + + int id = buttonView.getId(); + setCheckedId(id); + } + } + + /** + *

A pass-through listener acts upon the events and dispatches them + * to another listener. This allows the table layout to set its own internal + * hierarchy change listener without preventing the user to setup his.

+ */ + private class PassThroughHierarchyChangeListener implements + ViewGroup.OnHierarchyChangeListener { + private ViewGroup.OnHierarchyChangeListener mOnHierarchyChangeListener; + + public void traverseTree(View view) { + if (view instanceof RadioButton) { + int id = view.getId(); + // generates an id if it's missing + if (id == View.NO_ID) { + id = View.generateViewId(); + view.setId(id); + } + ((RadioButton) view).setOnCheckedChangeListener( + mChildOnCheckedChangeListener); + } + if (!(view instanceof ViewGroup)) { + return; + } + ViewGroup viewGroup = (ViewGroup) view; + if (viewGroup.getChildCount() == 0) { + return; + } + for (int i = 0; i < viewGroup.getChildCount(); i++) { + traverseTree(viewGroup.getChildAt(i)); + } + } + + /** + * {@inheritDoc} + */ + public void onChildViewAdded(View parent, View child) { + traverseTree(child); + if (parent == RadioGroupPlus.this && child instanceof RadioButton) { + int id = child.getId(); + // generates an id if it's missing + if (id == View.NO_ID) { + id = View.generateViewId(); + child.setId(id); + } + ((RadioButton) child).setOnCheckedChangeListener( + mChildOnCheckedChangeListener); + } + + if (mOnHierarchyChangeListener != null) { + mOnHierarchyChangeListener.onChildViewAdded(parent, child); + } + } + + /** + * {@inheritDoc} + */ + public void onChildViewRemoved(View parent, View child) { + if (parent == RadioGroupPlus.this && child instanceof RadioButton) { + ((RadioButton) child).setOnCheckedChangeListener(null); + } + + if (mOnHierarchyChangeListener != null) { + mOnHierarchyChangeListener.onChildViewRemoved(parent, child); + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/org/libsdl/app/SDL.java b/app/src/main/java/org/libsdl/app/SDL.java new file mode 100644 index 0000000..cfe4830 --- /dev/null +++ b/app/src/main/java/org/libsdl/app/SDL.java @@ -0,0 +1,37 @@ +package org.libsdl.app; + +import android.content.Context; + +/** + SDL library initialization +*/ +public class SDL { + + // This function should be called first and sets up the native code + // so it can call into the Java classes + public static void setupJNI() { + SDLActivity.nativeSetupJNI(); + SDLAudioManager.nativeSetupJNI(); + SDLControllerManager.nativeSetupJNI(); + } + + // This function should be called each time the activity is started + public static void initialize() { + setContext(null); + + SDLActivity.initialize(); + SDLAudioManager.initialize(); + SDLControllerManager.initialize(); + } + + // This function stores the current activity (SDL or not) + public static void setContext(Context context) { + mContext = context; + } + + public static Context getContext() { + return mContext; + } + + protected static Context mContext; +} diff --git a/app/src/main/java/org/libsdl/app/SDLActivity.java b/app/src/main/java/org/libsdl/app/SDLActivity.java new file mode 100644 index 0000000..c12258d --- /dev/null +++ b/app/src/main/java/org/libsdl/app/SDLActivity.java @@ -0,0 +1,1721 @@ +package org.libsdl.app; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Arrays; +import java.lang.reflect.Method; + +import android.app.*; +import android.content.*; +import android.content.res.Configuration; +import android.text.InputType; +import android.view.*; +import android.view.inputmethod.BaseInputConnection; +import android.view.inputmethod.EditorInfo; +import android.view.inputmethod.InputConnection; +import android.view.inputmethod.InputMethodManager; +import android.widget.RelativeLayout; +import android.widget.Button; +import android.widget.LinearLayout; +import android.widget.TextView; +import android.os.*; +import android.util.DisplayMetrics; +import android.util.Log; +import android.util.SparseArray; +import android.graphics.*; +import android.graphics.drawable.Drawable; +import android.hardware.*; +import android.content.pm.ActivityInfo; +import android.content.pm.PackageManager; +import android.content.pm.ApplicationInfo; + +import androidx.appcompat.app.AppCompatActivity; + +/** + SDL Activity +*/ +public class SDLActivity extends AppCompatActivity { + private static final String TAG = "SDL"; + + public static boolean mIsResumedCalled, mIsSurfaceReady, mHasFocus; + + // Handle the state of the native layer + public enum NativeState { + INIT, RESUMED, PAUSED + } + + public static NativeState mNextNativeState; + public static NativeState mCurrentNativeState; + + public static boolean mExitCalledFromJava; + + /** If shared libraries (e.g. SDL or the native application) could not be loaded. */ + public static boolean mBrokenLibraries; + + // If we want to separate mouse and touch events. + // This is only toggled in native code when a hint is set! + public static boolean mSeparateMouseAndTouch; + + // Main components + protected static SDLActivity mSingleton; + protected static SDLSurface mSurface; + protected static View mTextEdit; + protected static boolean mScreenKeyboardShown; + protected static ViewGroup mLayout; + protected static SDLClipboardHandler mClipboardHandler; + + + // This is what SDL runs in. It invokes SDL_main(), eventually + protected static Thread mSDLThread; + + /** + * This method returns the name of the shared object with the application entry point + * It can be overridden by derived classes. + */ + protected String getMainSharedObject() { + String library; + String[] libraries = SDLActivity.mSingleton.getLibraries(); + if (libraries.length > 0) { + library = "lib" + libraries[libraries.length - 1] + ".so"; + } else { + library = "libmain.so"; + } + return library; + } + + /** + * This method returns the name of the application entry point + * It can be overridden by derived classes. + */ + protected String getMainFunction() { + return "SDL_main"; + } + + /** + * This method is called by SDL before loading the native shared libraries. + * It can be overridden to provide names of shared libraries to be loaded. + * The default implementation returns the defaults. It never returns null. + * An array returned by a new implementation must at least contain "SDL2". + * Also keep in mind that the order the libraries are loaded may matter. + * @return names of shared libraries to be loaded (e.g. "SDL2", "main"). + */ + protected String[] getLibraries() { + return new String[] { + "SDL2", + // "SDL2_image", + // "SDL2_mixer", + // "SDL2_net", + // "SDL2_ttf", + "main" + }; + } + + // Load the .so + public void loadLibraries() { + for (String lib : getLibraries()) { + System.loadLibrary(lib); + } + } + + /** + * This method is called by SDL before starting the native application thread. + * It can be overridden to provide the arguments after the application name. + * The default implementation returns an empty array. It never returns null. + * @return arguments for the native application. + */ + protected String[] getArguments() { + return new String[0]; + } + + public static void initialize() { + // The static nature of the singleton and Android quirkyness force us to initialize everything here + // Otherwise, when exiting the app and returning to it, these variables *keep* their pre exit values + mSingleton = null; + mSurface = null; + mTextEdit = null; + mLayout = null; + mClipboardHandler = null; + mSDLThread = null; + mExitCalledFromJava = false; + mBrokenLibraries = false; + mIsResumedCalled = false; + mIsSurfaceReady = false; + mHasFocus = true; + mNextNativeState = NativeState.INIT; + mCurrentNativeState = NativeState.INIT; + } + + // Setup + @Override + protected void onCreate(Bundle savedInstanceState) { + Log.v(TAG, "Device: " + android.os.Build.DEVICE); + Log.v(TAG, "Model: " + android.os.Build.MODEL); + Log.v(TAG, "onCreate()"); + super.onCreate(savedInstanceState); + + // Load shared libraries + String errorMsgBrokenLib = ""; + try { + loadLibraries(); + } catch(UnsatisfiedLinkError e) { + System.err.println(e.getMessage()); + mBrokenLibraries = true; + errorMsgBrokenLib = e.getMessage(); + } catch(Exception e) { + System.err.println(e.getMessage()); + mBrokenLibraries = true; + errorMsgBrokenLib = e.getMessage(); + } + + if (mBrokenLibraries) + { + mSingleton = this; + AlertDialog.Builder dlgAlert = new AlertDialog.Builder(this); + dlgAlert.setMessage("An error occurred while trying to start the application. Please try again and/or reinstall." + + System.getProperty("line.separator") + + System.getProperty("line.separator") + + "Error: " + errorMsgBrokenLib); + dlgAlert.setTitle("SDL Error"); + dlgAlert.setPositiveButton("Exit", + new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog,int id) { + // if this button is clicked, close current activity + SDLActivity.mSingleton.finish(); + } + }); + dlgAlert.setCancelable(false); + dlgAlert.create().show(); + + return; + } + + // Set up JNI + SDL.setupJNI(); + + // Initialize state + SDL.initialize(); + + // So we can call stuff from static callbacks + mSingleton = this; + SDL.setContext(this); + + if (Build.VERSION.SDK_INT >= 11) { + mClipboardHandler = new SDLClipboardHandler_API11(); + } else { + /* Before API 11, no clipboard notification (eg no SDL_CLIPBOARDUPDATE) */ + mClipboardHandler = new SDLClipboardHandler_Old(); + } + + //Vectras: override + // Set up the surface + //mSurface = new SDLSurface(getApplication()); + + //Vectras: override + //mLayout = new RelativeLayout(this); + //mLayout.addView(mSurface); + + //setContentView(mLayout); + + setWindowStyle(false); + + // Get filename from "Open with" of another application + Intent intent = getIntent(); + if (intent != null && intent.getData() != null) { + String filename = intent.getData().getPath(); + if (filename != null) { + Log.v(TAG, "Got filename: " + filename); + SDLActivity.onNativeDropFile(filename); + } + } + } + + // Events + @Override + protected void onPause() { + Log.v(TAG, "onPause()"); + super.onPause(); + mNextNativeState = NativeState.PAUSED; + mIsResumedCalled = false; + + if (SDLActivity.mBrokenLibraries) { + return; + } + + SDLActivity.handleNativeState(); + } + + @Override + protected void onResume() { + Log.v(TAG, "onResume()"); + super.onResume(); + mNextNativeState = NativeState.RESUMED; + mIsResumedCalled = true; + + if (SDLActivity.mBrokenLibraries) { + return; + } + + SDLActivity.handleNativeState(); + } + + + @Override + public void onWindowFocusChanged(boolean hasFocus) { + super.onWindowFocusChanged(hasFocus); + Log.v(TAG, "onWindowFocusChanged(): " + hasFocus); + + if (SDLActivity.mBrokenLibraries) { + return; + } + + SDLActivity.mHasFocus = hasFocus; + if (hasFocus) { + mNextNativeState = NativeState.RESUMED; + } else { + mNextNativeState = NativeState.PAUSED; + } + + SDLActivity.handleNativeState(); + } + + @Override + public void onLowMemory() { + Log.v(TAG, "onLowMemory()"); + super.onLowMemory(); + + if (SDLActivity.mBrokenLibraries) { + return; + } + + SDLActivity.nativeLowMemory(); + } + + @Override + protected void onDestroy() { + Log.v(TAG, "onDestroy()"); + + if (SDLActivity.mBrokenLibraries) { + super.onDestroy(); + // Reset everything in case the user re opens the app + SDLActivity.initialize(); + return; + } + + mNextNativeState = NativeState.PAUSED; + SDLActivity.handleNativeState(); + + // Send a quit message to the application + SDLActivity.mExitCalledFromJava = true; + SDLActivity.nativeQuit(); + + // Now wait for the SDL thread to quit + if (SDLActivity.mSDLThread != null) { + try { + SDLActivity.mSDLThread.join(); + } catch(Exception e) { + Log.v(TAG, "Problem stopping thread: " + e); + } + SDLActivity.mSDLThread = null; + + //Log.v(TAG, "Finished waiting for SDL thread"); + } + + super.onDestroy(); + + // Reset everything in case the user re opens the app + SDLActivity.initialize(); + } + + @Override + public boolean dispatchKeyEvent(KeyEvent event) { + + if (SDLActivity.mBrokenLibraries) { + return false; + } + + int keyCode = event.getKeyCode(); + // Ignore certain special keys so they're handled by Android + if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN || + keyCode == KeyEvent.KEYCODE_VOLUME_UP || + keyCode == KeyEvent.KEYCODE_CAMERA || + keyCode == KeyEvent.KEYCODE_ZOOM_IN || /* API 11 */ + keyCode == KeyEvent.KEYCODE_ZOOM_OUT /* API 11 */ + ) { + return false; + } + return super.dispatchKeyEvent(event); + } + + /* Transition to next state */ + public static void handleNativeState() { + + if (mNextNativeState == mCurrentNativeState) { + // Already in same state, discard. + return; + } + + // Try a transition to init state + if (mNextNativeState == NativeState.INIT) { + + mCurrentNativeState = mNextNativeState; + return; + } + + // Try a transition to paused state + if (mNextNativeState == NativeState.PAUSED) { + nativePause(); + if (mSurface != null) + mSurface.handlePause(); + mCurrentNativeState = mNextNativeState; + return; + } + + // Try a transition to resumed state + if (mNextNativeState == NativeState.RESUMED) { + if (mIsSurfaceReady && mHasFocus && mIsResumedCalled) { + if (mSDLThread == null) { + // This is the entry point to the C app. + // Start up the C app thread and enable sensor input for the first time + // FIXME: Why aren't we enabling sensor input at start? + + mSDLThread = new Thread(new SDLMain(), "SDLThread"); + mSurface.enableSensor(Sensor.TYPE_ACCELEROMETER, true); + mSDLThread.start(); + } + + nativeResume(); + mSurface.handleResume(); + mCurrentNativeState = mNextNativeState; + } + } + } + + /* The native thread has finished */ + public static void handleNativeExit() { + SDLActivity.mSDLThread = null; + mSingleton.finish(); + } + + + // Messages from the SDLMain thread + static final int COMMAND_CHANGE_TITLE = 1; + static final int COMMAND_CHANGE_WINDOW_STYLE = 2; + static final int COMMAND_TEXTEDIT_HIDE = 3; + static final int COMMAND_SET_KEEP_SCREEN_ON = 5; + + protected static final int COMMAND_USER = 0x8000; + + /** + * This method is called by SDL if SDL did not handle a message itself. + * This happens if a received message contains an unsupported command. + * Method can be overwritten to handle Messages in a different class. + * @param command the command of the message. + * @param param the parameter of the message. May be null. + * @return if the message was handled in overridden method. + */ + protected boolean onUnhandledMessage(int command, Object param) { + return false; + } + + /** + * A Handler class for Messages from native SDL applications. + * It uses current Activities as target (e.g. for the title). + * static to prevent implicit references to enclosing object. + */ + protected static class SDLCommandHandler extends Handler { + @Override + public void handleMessage(Message msg) { + Context context = SDL.getContext(); + if (context == null) { + Log.e(TAG, "error handling message, getContext() returned null"); + return; + } + switch (msg.arg1) { + case COMMAND_CHANGE_TITLE: + if (context instanceof Activity) { + ((Activity) context).setTitle((String)msg.obj); + } else { + Log.e(TAG, "error handling message, getContext() returned no Activity"); + } + break; + case COMMAND_CHANGE_WINDOW_STYLE: + if (Build.VERSION.SDK_INT < 19) { + // This version of Android doesn't support the immersive fullscreen mode + break; + } +/* This needs more testing, per bug 4096 - Enabling fullscreen on Android causes the app to toggle fullscreen mode continuously in a loop + *** + if (context instanceof Activity) { + Window window = ((Activity) context).getWindow(); + if (window != null) { + if ((msg.obj instanceof Integer) && (((Integer) msg.obj).intValue() != 0)) { + int flags = View.SYSTEM_UI_FLAG_LAYOUT_STABLE | + View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | + View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | + View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | + View.SYSTEM_UI_FLAG_FULLSCREEN | + View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY; + window.getDecorView().setSystemUiVisibility(flags); + window.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN); + } else { + int flags = View.SYSTEM_UI_FLAG_LAYOUT_STABLE; + window.getDecorView().setSystemUiVisibility(flags); + window.clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN); + } + } + } else { + Log.e(TAG, "error handling message, getContext() returned no Activity"); + } +***/ + break; + case COMMAND_TEXTEDIT_HIDE: + if (mTextEdit != null) { + // Note: On some devices setting view to GONE creates a flicker in landscape. + // Setting the View's sizes to 0 is similar to GONE but without the flicker. + // The sizes will be set to useful values when the keyboard is shown again. + mTextEdit.setLayoutParams(new RelativeLayout.LayoutParams(0, 0)); + + InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE); + imm.hideSoftInputFromWindow(mTextEdit.getWindowToken(), 0); + + mScreenKeyboardShown = false; + } + break; + case COMMAND_SET_KEEP_SCREEN_ON: + { + if (context instanceof Activity) { + Window window = ((Activity) context).getWindow(); + if (window != null) { + if ((msg.obj instanceof Integer) && (((Integer) msg.obj).intValue() != 0)) { + window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); + } else { + window.clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); + } + } + } + break; + } + default: + if ((context instanceof SDLActivity) && !((SDLActivity) context).onUnhandledMessage(msg.arg1, msg.obj)) { + Log.e(TAG, "error handling message, command is " + msg.arg1); + } + } + } + } + + // Handler for the messages + Handler commandHandler = new SDLCommandHandler(); + + // Send a message from the SDLMain thread + boolean sendCommand(int command, Object data) { + Message msg = commandHandler.obtainMessage(); + msg.arg1 = command; + msg.obj = data; + return commandHandler.sendMessage(msg); + } + + // C functions we call + public static native int nativeSetupJNI(); + public static native int nativeRunMain(String library, String function, Object arguments); + public static native void nativeLowMemory(); + public static native void nativeQuit(); + public static native void nativePause(); + public static native void nativeResume(); + public static native void onNativeDropFile(String filename); + public static native void onNativeResize(int x, int y, int format, float rate); + public static native void onNativeKeyDown(int keycode); + public static native void onNativeKeyUp(int keycode); + public static native void onNativeKeyboardFocusLost(); + private static native void onNativeMouse(int button, int action, float x, float y); + private static native void onNativeTouch(int touchDevId, int pointerFingerId, + int action, float x, + float y, float p); + public static native void onNativeAccel(float x, float y, float z); + public static native void onNativeClipboardChanged(); + public static native void onNativeSurfaceChanged(); + public static native void onNativeSurfaceDestroyed(); + public static native String nativeGetHint(String name); + public static native void nativeSetenv(String name, String value); + + public static void onSDLNativeMouse(int button, int action, float x, float y){ + Log.d(TAG, "onSDLNativeMouse: B: " + button + ", A: " + action + ", X: " + x + ", Y: " + y); + onNativeMouse(button, action, x, y); + } + public static void onSDLNativeTouch(int touchDevId, int pointerFingerId, int action, float x, float y, float p){ + Log.d(TAG, "onSDLNativeTouch: F: " + pointerFingerId + ", A: " + action + ", X: " + x + ", Y: " + y); + onNativeTouch(touchDevId, pointerFingerId, action, x, y, p); + + } + /** + * This method is called by SDL using JNI. + */ + public static boolean setActivityTitle(String title) { + // Called from SDLMain() thread and can't directly affect the view + return mSingleton.sendCommand(COMMAND_CHANGE_TITLE, title); + } + + /** + * This method is called by SDL using JNI. + */ + public static void setWindowStyle(boolean fullscreen) { + // Called from SDLMain() thread and can't directly affect the view + mSingleton.sendCommand(COMMAND_CHANGE_WINDOW_STYLE, fullscreen ? 1 : 0); + } + + /** + * This method is called by SDL using JNI. + * This is a static method for JNI convenience, it calls a non-static method + * so that is can be overridden + */ + public static void setOrientation(int w, int h, boolean resizable, String hint) + { + if (mSingleton != null) { + mSingleton.setOrientationBis(w, h, resizable, hint); + } + } + + /** + * This can be overridden + */ + public void setOrientationBis(int w, int h, boolean resizable, String hint) + { + int orientation = -1; + + if (hint.contains("LandscapeRight") && hint.contains("LandscapeLeft")) { + orientation = ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE; + } else if (hint.contains("LandscapeRight")) { + orientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE; + } else if (hint.contains("LandscapeLeft")) { + orientation = ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE; + } else if (hint.contains("Portrait") && hint.contains("PortraitUpsideDown")) { + orientation = ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT; + } else if (hint.contains("Portrait")) { + orientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT; + } else if (hint.contains("PortraitUpsideDown")) { + orientation = ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT; + } + + /* no valid hint */ + if (orientation == -1) { + if (resizable) { + /* no fixed orientation */ + } else { + if (w > h) { + orientation = ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE; + } else { + orientation = ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT; + } + } + } + + Log.v("SDL", "setOrientation() orientation=" + orientation + " width=" + w +" height="+ h +" resizable=" + resizable + " hint=" + hint); + if (orientation != -1) { + mSingleton.setRequestedOrientation(orientation); + } + } + + + /** + * This method is called by SDL using JNI. + */ + public static boolean isScreenKeyboardShown() + { + if (mTextEdit == null) { + return false; + } + + if (!mScreenKeyboardShown) { + return false; + } + + InputMethodManager imm = (InputMethodManager) SDL.getContext().getSystemService(Context.INPUT_METHOD_SERVICE); + return imm.isAcceptingText(); + + } + + /** + * This method is called by SDL using JNI. + */ + public static boolean sendMessage(int command, int param) { + if (mSingleton == null) { + return false; + } + return mSingleton.sendCommand(command, Integer.valueOf(param)); + } + + /** + * This method is called by SDL using JNI. + */ + public static Context getContext() { + return SDL.getContext(); + } + + /** + * This method is called by SDL using JNI. + */ + public static boolean isAndroidTV() { + UiModeManager uiModeManager = (UiModeManager) getContext().getSystemService(UI_MODE_SERVICE); + return (uiModeManager.getCurrentModeType() == Configuration.UI_MODE_TYPE_TELEVISION); + } + + /** + * This method is called by SDL using JNI. + */ + public static DisplayMetrics getDisplayDPI() { + return getContext().getResources().getDisplayMetrics(); + } + + /** + * This method is called by SDL using JNI. + */ + public static boolean getManifestEnvironmentVariables() { + try { + ApplicationInfo applicationInfo = getContext().getPackageManager().getApplicationInfo(getContext().getPackageName(), PackageManager.GET_META_DATA); + Bundle bundle = applicationInfo.metaData; + if (bundle == null) { + return false; + } + String prefix = "SDL_ENV."; + final int trimLength = prefix.length(); + for (String key : bundle.keySet()) { + if (key.startsWith(prefix)) { + String name = key.substring(trimLength); + String value = bundle.get(key).toString(); + nativeSetenv(name, value); + } + } + /* environment variables set! */ + return true; + } catch (Exception e) { + Log.v("SDL", "exception " + e.toString()); + } + return false; + } + + static class ShowTextInputTask implements Runnable { + /* + * This is used to regulate the pan&scan method to have some offset from + * the bottom edge of the input region and the top edge of an input + * method (soft keyboard) + */ + static final int HEIGHT_PADDING = 15; + + public int x, y, w, h; + + public ShowTextInputTask(int x, int y, int w, int h) { + this.x = x; + this.y = y; + this.w = w; + this.h = h; + } + + @Override + public void run() { + RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(w, h + HEIGHT_PADDING); + params.leftMargin = x; + params.topMargin = y; + + if (mTextEdit == null) { + mTextEdit = new DummyEdit(SDL.getContext()); + + mLayout.addView(mTextEdit, params); + } else { + mTextEdit.setLayoutParams(params); + } + + mTextEdit.setVisibility(View.VISIBLE); + mTextEdit.requestFocus(); + + InputMethodManager imm = (InputMethodManager) SDL.getContext().getSystemService(Context.INPUT_METHOD_SERVICE); + imm.showSoftInput(mTextEdit, 0); + + mScreenKeyboardShown = true; + } + } + + /** + * This method is called by SDL using JNI. + */ + public static boolean showTextInput(int x, int y, int w, int h) { + // Transfer the task to the main thread as a Runnable + return mSingleton.commandHandler.post(new ShowTextInputTask(x, y, w, h)); + } + + public static boolean isTextInputEvent(KeyEvent event) { + + // Key pressed with Ctrl should be sent as SDL_KEYDOWN/SDL_KEYUP and not SDL_TEXTINPUT + if (Build.VERSION.SDK_INT >= 11) { + if (event.isCtrlPressed()) { + return false; + } + } + + return event.isPrintingKey() || event.getKeyCode() == KeyEvent.KEYCODE_SPACE; + } + + /** + * This method is called by SDL using JNI. + */ + public static Surface getNativeSurface() { + if (SDLActivity.mSurface == null) { + return null; + } + return SDLActivity.mSurface.getNativeSurface(); + } + + // Input + + /** + * This method is called by SDL using JNI. + * @return an array which may be empty but is never null. + */ + public static int[] inputGetInputDeviceIds(int sources) { + int[] ids = InputDevice.getDeviceIds(); + int[] filtered = new int[ids.length]; + int used = 0; + for (int i = 0; i < ids.length; ++i) { + InputDevice device = InputDevice.getDevice(ids[i]); + if ((device != null) && ((device.getSources() & sources) != 0)) { + filtered[used++] = device.getId(); + } + } + return Arrays.copyOf(filtered, used); + } + + // APK expansion files support + + /** com.android.vending.expansion.zipfile.ZipResourceFile object or null. */ + private static Object expansionFile; + + /** com.android.vending.expansion.zipfile.ZipResourceFile's getInputStream() or null. */ + private static Method expansionFileMethod; + + /** + * This method is called by SDL using JNI. + * @return an InputStream on success or null if no expansion file was used. + * @throws IOException on errors. Message is set for the SDL error message. + */ + public static InputStream openAPKExpansionInputStream(String fileName) throws IOException { + // Get a ZipResourceFile representing a merger of both the main and patch files + if (expansionFile == null) { + String mainHint = nativeGetHint("SDL_ANDROID_APK_EXPANSION_MAIN_FILE_VERSION"); + if (mainHint == null) { + return null; // no expansion use if no main version was set + } + String patchHint = nativeGetHint("SDL_ANDROID_APK_EXPANSION_PATCH_FILE_VERSION"); + if (patchHint == null) { + return null; // no expansion use if no patch version was set + } + + Integer mainVersion; + Integer patchVersion; + try { + mainVersion = Integer.valueOf(mainHint); + patchVersion = Integer.valueOf(patchHint); + } catch (NumberFormatException ex) { + ex.printStackTrace(); + throw new IOException("No valid file versions set for APK expansion files", ex); + } + + try { + // To avoid direct dependency on Google APK expansion library that is + // not a part of Android SDK we access it using reflection + expansionFile = Class.forName("com.android.vending.expansion.zipfile.APKExpansionSupport") + .getMethod("getAPKExpansionZipFile", Context.class, int.class, int.class) + .invoke(null, SDL.getContext(), mainVersion, patchVersion); + + expansionFileMethod = expansionFile.getClass() + .getMethod("getInputStream", String.class); + } catch (Exception ex) { + ex.printStackTrace(); + expansionFile = null; + expansionFileMethod = null; + throw new IOException("Could not access APK expansion support library", ex); + } + } + + // Get an input stream for a known file inside the expansion file ZIPs + InputStream fileStream; + try { + fileStream = (InputStream)expansionFileMethod.invoke(expansionFile, fileName); + } catch (Exception ex) { + // calling "getInputStream" failed + ex.printStackTrace(); + throw new IOException("Could not open stream from APK expansion file", ex); + } + + if (fileStream == null) { + // calling "getInputStream" was successful but null was returned + throw new IOException("Could not find path in APK expansion file"); + } + + return fileStream; + } + + // Messagebox + + /** Result of current messagebox. Also used for blocking the calling thread. */ + protected final int[] messageboxSelection = new int[1]; + + /** Id of current dialog. */ + protected int dialogs = 0; + + /** + * This method is called by SDL using JNI. + * Shows the messagebox from UI thread and block calling thread. + * buttonFlags, buttonIds and buttonTexts must have same length. + * @param buttonFlags array containing flags for every button. + * @param buttonIds array containing id for every button. + * @param buttonTexts array containing text for every button. + * @param colors null for default or array of length 5 containing colors. + * @return button id or -1. + */ + public int messageboxShowMessageBox( + final int flags, + final String title, + final String message, + final int[] buttonFlags, + final int[] buttonIds, + final String[] buttonTexts, + final int[] colors) { + + messageboxSelection[0] = -1; + + // sanity checks + + if ((buttonFlags.length != buttonIds.length) && (buttonIds.length != buttonTexts.length)) { + return -1; // implementation broken + } + + // collect arguments for Dialog + + final Bundle args = new Bundle(); + args.putInt("flags", flags); + args.putString("title", title); + args.putString("message", message); + args.putIntArray("buttonFlags", buttonFlags); + args.putIntArray("buttonIds", buttonIds); + args.putStringArray("buttonTexts", buttonTexts); + args.putIntArray("colors", colors); + + // trigger Dialog creation on UI thread + + runOnUiThread(new Runnable() { + @Override + public void run() { + showDialog(dialogs++, args); + } + }); + + // block the calling thread + + synchronized (messageboxSelection) { + try { + messageboxSelection.wait(); + } catch (InterruptedException ex) { + ex.printStackTrace(); + return -1; + } + } + + // return selected value + + return messageboxSelection[0]; + } + + @Override + protected Dialog onCreateDialog(int ignore, Bundle args) { + + // TODO set values from "flags" to messagebox dialog + + // get colors + + int[] colors = args.getIntArray("colors"); + int backgroundColor; + int textColor; + int buttonBorderColor; + int buttonBackgroundColor; + int buttonSelectedColor; + if (colors != null) { + int i = -1; + backgroundColor = colors[++i]; + textColor = colors[++i]; + buttonBorderColor = colors[++i]; + buttonBackgroundColor = colors[++i]; + buttonSelectedColor = colors[++i]; + } else { + backgroundColor = Color.TRANSPARENT; + textColor = Color.TRANSPARENT; + buttonBorderColor = Color.TRANSPARENT; + buttonBackgroundColor = Color.TRANSPARENT; + buttonSelectedColor = Color.TRANSPARENT; + } + + // create dialog with title and a listener to wake up calling thread + + final Dialog dialog = new Dialog(this); + dialog.setTitle(args.getString("title")); + dialog.setCancelable(false); + dialog.setOnDismissListener(new DialogInterface.OnDismissListener() { + @Override + public void onDismiss(DialogInterface unused) { + synchronized (messageboxSelection) { + messageboxSelection.notify(); + } + } + }); + + // create text + + TextView message = new TextView(this); + message.setGravity(Gravity.CENTER); + message.setText(args.getString("message")); + if (textColor != Color.TRANSPARENT) { + message.setTextColor(textColor); + } + + // create buttons + + int[] buttonFlags = args.getIntArray("buttonFlags"); + int[] buttonIds = args.getIntArray("buttonIds"); + String[] buttonTexts = args.getStringArray("buttonTexts"); + + final SparseArray + + + + + + + +