├── fabric ├── wslgradlew ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── settings.gradle ├── .gitignore ├── preprocess.sh ├── gradle.properties ├── gradlew.bat ├── build.gradle └── gradlew ├── forge ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── wslgradlew ├── .gitignore ├── gradle.properties ├── gradlew.bat ├── gradlew └── build.gradle ├── src ├── fabric │ ├── resources │ │ ├── assets │ │ │ └── modid │ │ │ │ └── icon.png │ │ ├── cocoafab.mixins.json │ │ ├── fabric.mod.json │ │ └── cocoainput.accesswidener │ └── java │ │ └── jp │ │ └── axer │ │ └── cocoainput │ │ ├── loader │ │ ├── CocoaInputModMenu.java │ │ └── FabricLoader.java │ │ └── mixin │ │ └── MinecraftMixin.java ├── main │ ├── resources │ │ ├── win │ │ │ └── libwincocoainput.dll │ │ └── cocoainput.mixins.json │ └── java │ │ └── jp │ │ └── axer │ │ └── cocoainput │ │ ├── util │ │ ├── WrapperUtil.java │ │ ├── Tuple3.java │ │ ├── ConfigPack.java │ │ ├── Rect.java │ │ ├── ModLogger.java │ │ ├── FCConfig.java │ │ ├── PreeditFormatter.java │ │ └── TinyConfig.java │ │ ├── plugin │ │ ├── CocoaInputController.java │ │ ├── IMEOperator.java │ │ └── IMEReceiver.java │ │ ├── arch │ │ ├── dummy │ │ │ ├── DummyIMEOperator.java │ │ │ └── DummyController.java │ │ ├── darwin │ │ │ ├── Handle.java │ │ │ ├── DarwinController.java │ │ │ ├── CallbackFunction.java │ │ │ └── DarwinIMEOperator.java │ │ ├── x11 │ │ │ ├── Handle.java │ │ │ ├── X11IMEOperator.java │ │ │ ├── Logger.java │ │ │ └── X11Controller.java │ │ └── win │ │ │ ├── WinIMEOperator.java │ │ │ ├── Handle.java │ │ │ ├── Logger.java │ │ │ └── WinController.java │ │ ├── mixin │ │ ├── SharedConstantsMixin.java │ │ ├── SignEditScreenMixin.java │ │ ├── BookEditScreenMixin.java │ │ └── EditBoxMixin.java │ │ ├── wrapper │ │ ├── EditBoxWrapper.java │ │ ├── SignEditScreenWrapper.java │ │ └── BookEditScreenWrapper.java │ │ └── CocoaInput.java └── forge │ ├── resources │ ├── pack.mcmeta │ └── META-INF │ │ ├── accesstransformer.cfg │ │ └── mods.toml │ └── java │ └── jp │ └── axer │ └── cocoainput │ └── loader │ └── ForgeLoader.java ├── libcocoainput ├── darwin │ ├── libcocoainput.xcodeproj │ │ ├── project.xcworkspace │ │ │ ├── contents.xcworkspacedata │ │ │ ├── xcuserdata │ │ │ │ └── axer.xcuserdatad │ │ │ │ │ └── UserInterfaceState.xcuserstate │ │ │ └── xcshareddata │ │ │ │ └── IDEWorkspaceChecks.plist │ │ ├── xcuserdata │ │ │ └── axer.xcuserdatad │ │ │ │ └── xcschemes │ │ │ │ └── xcschememanagement.plist │ │ └── project.pbxproj │ └── libcocoainput │ │ ├── MinecraftView.m │ │ ├── Logger.h │ │ ├── MinecraftView.h │ │ ├── Makefile │ │ ├── Logger.m │ │ ├── cocoainput.h │ │ ├── DataManager.h │ │ ├── cocoainput.m │ │ └── DataManager.m ├── win │ ├── .project │ ├── logger.h │ ├── libwincocoainput.h │ ├── Makefile │ ├── logger.c │ └── libwincocoainput.c └── x11 │ ├── logger.h │ ├── Makefile │ ├── logger.c │ ├── libx11cocoainput.h │ └── libx11cocoainput.c ├── .gitignore ├── .github └── ISSUE_TEMPLATE │ └── bug_report.md ├── README.MD └── LICENSE /fabric/wslgradlew: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | cmd.exe /c 'SET JAVA_HOME=C:\Program Files\Eclipse Adoptium\jdk-17.0.1.12-hotspot&gradlew '"$@" 3 | -------------------------------------------------------------------------------- /forge/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Axeryok/CocoaInput/HEAD/forge/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /forge/wslgradlew: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | cmd.exe /c 'SET JAVA_HOME=C:\Program Files\Eclipse Adoptium\jdk-17.0.1.12-hotspot&gradlew '"$@" 3 | -------------------------------------------------------------------------------- /fabric/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Axeryok/CocoaInput/HEAD/fabric/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /src/fabric/resources/assets/modid/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Axeryok/CocoaInput/HEAD/src/fabric/resources/assets/modid/icon.png -------------------------------------------------------------------------------- /src/main/resources/win/libwincocoainput.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Axeryok/CocoaInput/HEAD/src/main/resources/win/libwincocoainput.dll -------------------------------------------------------------------------------- /src/fabric/resources/cocoafab.mixins.json: -------------------------------------------------------------------------------- 1 | { 2 | "package":"jp.axer.cocoainput.mixin", 3 | "mixins":[ 4 | "MinecraftMixin" ], 5 | "required":true 6 | } -------------------------------------------------------------------------------- /fabric/settings.gradle: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | repositories { 3 | maven { 4 | name = 'Fabric' 5 | url = 'https://maven.fabricmc.net/' 6 | } 7 | gradlePluginPortal() 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /fabric/.gitignore: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | .DS_Store 4 | *.dylib 5 | *.so 6 | *.dll 7 | *.o 8 | 9 | 10 | !.gitignore 11 | !gradle 12 | !gradle.properties 13 | !gradlew 14 | !gradlew.bat 15 | !wslgradlew 16 | !preprocess.sh 17 | !build.gradle 18 | !settings.gradle 19 | -------------------------------------------------------------------------------- /forge/.gitignore: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | .DS_Store 4 | *.dylib 5 | *.so 6 | *.dll 7 | *.o 8 | 9 | 10 | !.gitignore 11 | !gradle 12 | !gradle.properties 13 | !gradlew 14 | !gradlew.bat 15 | !wslgradlew 16 | !preprocess.sh 17 | !build.gradle 18 | !settings.gradle 19 | -------------------------------------------------------------------------------- /forge/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /src/forge/resources/pack.mcmeta: -------------------------------------------------------------------------------- 1 | { 2 | "pack": { 3 | "description": "examplemod resources", 4 | "pack_format": 4, 5 | "_comment": "A pack_format of 4 requires json lang files. Note: we require v4 pack meta for all mods." 6 | } 7 | } -------------------------------------------------------------------------------- /src/main/resources/cocoainput.mixins.json: -------------------------------------------------------------------------------- 1 | { 2 | "package":"jp.axer.cocoainput.mixin", 3 | "mixins":[ 4 | "SharedConstantsMixin", 5 | "EditBoxMixin", 6 | "SignEditScreenMixin", 7 | "BookEditScreenMixin" 8 | ], 9 | "required":true 10 | } -------------------------------------------------------------------------------- /fabric/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.2-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /forge/gradle.properties: -------------------------------------------------------------------------------- 1 | # Sets default memory used for gradle commands. Can be overridden by user or command line properties. 2 | # This is required to provide enough memory for the Minecraft decompilation process. 3 | org.gradle.jvmargs=-Xmx3G 4 | org.gradle.daemon=false -------------------------------------------------------------------------------- /libcocoainput/darwin/libcocoainput.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /libcocoainput/darwin/libcocoainput.xcodeproj/project.xcworkspace/xcuserdata/axer.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Axeryok/CocoaInput/HEAD/libcocoainput/darwin/libcocoainput.xcodeproj/project.xcworkspace/xcuserdata/axer.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /libcocoainput/win/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | libwincocoainput 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /libcocoainput/win/logger.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | typedef void (*LogFunction)(const char *); 4 | 5 | 6 | void initLogPointer(LogFunction log,LogFunction error,LogFunction debug); 7 | 8 | void CILog(const char *msg,...); 9 | void CIError(const char *msg,...); 10 | void CIDebug(const char *msg,...); 11 | -------------------------------------------------------------------------------- /libcocoainput/x11/logger.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | typedef void (*LogFunction)(const char *); 4 | 5 | 6 | void initLogPointer(LogFunction log,LogFunction error,LogFunction debug); 7 | 8 | void CILog(const char *msg,...); 9 | void CIError(const char *msg,...); 10 | void CIDebug(const char *msg,...); 11 | -------------------------------------------------------------------------------- /src/main/java/jp/axer/cocoainput/util/WrapperUtil.java: -------------------------------------------------------------------------------- 1 | package jp.axer.cocoainput.util; 2 | 3 | import net.minecraft.client.gui.Font; 4 | import net.minecraft.client.gui.screens.Screen; 5 | 6 | 7 | public class WrapperUtil { 8 | public static Font makeFont(Screen owner) throws Exception { 9 | return owner.font; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /fabric/preprocess.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | rm -r src/autogen 3 | mkdir -p src/autogen/ 4 | cp -r ../src/main/* src/autogen/ 5 | mv src/autogen/resources/cocoainput.mixins.json src/autogen/java 6 | cd src/autogen/java 7 | find . -type f -print0 | xargs -0 sed -i -e 's/"refmap":"cocoainput.refmap.json",//g' 8 | mv cocoainput.mixins.json ../resources 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/main/java/jp/axer/cocoainput/plugin/CocoaInputController.java: -------------------------------------------------------------------------------- 1 | package jp.axer.cocoainput.plugin; 2 | 3 | import net.minecraft.client.gui.screens.Screen; 4 | 5 | public interface CocoaInputController { 6 | IMEOperator generateIMEOperator(IMEReceiver ime); //GuiTextFieldとかが作成された時に割り当てるIMEOperator生成処理を委託 7 | void screenOpenNotify(Screen sc); 8 | } 9 | -------------------------------------------------------------------------------- /libcocoainput/darwin/libcocoainput.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | .DS_Store 4 | *.dylib 5 | *.so 6 | *.dll 7 | *.o 8 | 9 | 10 | !.gitignore 11 | !src 12 | !libcocoainput 13 | !README.MD 14 | !build_lib_for_mac.sh 15 | !build_lib_for_win.sh 16 | !build_lib_for_x11.sh 17 | !build_lib_all.sh 18 | !build_cocoainput_all_platform.sh 19 | !TODO.txt 20 | !LICENSE 21 | 22 | libcocoainput/build 23 | 24 | !fabric 25 | !forge 26 | -------------------------------------------------------------------------------- /src/main/java/jp/axer/cocoainput/plugin/IMEOperator.java: -------------------------------------------------------------------------------- 1 | package jp.axer.cocoainput.plugin; 2 | 3 | public interface IMEOperator { 4 | void setFocused(boolean inFocused);//保持するIMEのフォーカスが変化した時に呼び出される 5 | void discardMarkedText();//実装してないので呼び出されない(いつか実装する) 6 | 7 | //TODO removeInstanceを実装する(現時点では呼ばれない) 8 | void removeInstance();//看板や本の編集が終わった時に呼び出される テキストフィールドは廃棄位置が曖昧なため呼び出されない 9 | 10 | } -------------------------------------------------------------------------------- /libcocoainput/win/libwincocoainput.h: -------------------------------------------------------------------------------- 1 | //#include 2 | #include 3 | #include 4 | 5 | #include "logger.h" 6 | 7 | 8 | 9 | void initialize( 10 | long hwnd, 11 | int*(*c_draw)(wchar_t*,int,int), 12 | void(*c_done)(wchar_t*), 13 | int (*c_rect)(float*), 14 | LogFunction log, 15 | LogFunction error, 16 | LogFunction debug 17 | ); 18 | 19 | 20 | 21 | 22 | void set_focus(int flag); 23 | -------------------------------------------------------------------------------- /libcocoainput/darwin/libcocoainput/MinecraftView.m: -------------------------------------------------------------------------------- 1 | // 2 | // MinecraftView.m 3 | // libcocoainput 4 | // 5 | // Created by Axer on 2019/03/23. 6 | // Copyright © 2019年 Axer. All rights reserved. 7 | // 8 | 9 | #import "MinecraftView.h" 10 | #import "DataManager.h" 11 | #import "Logger.h" 12 | 13 | @implementation MinecraftView 14 | 15 | - (id)init { 16 | self = [super init]; 17 | return self; 18 | } 19 | 20 | @end 21 | -------------------------------------------------------------------------------- /src/main/java/jp/axer/cocoainput/util/Tuple3.java: -------------------------------------------------------------------------------- 1 | package jp.axer.cocoainput.util; 2 | 3 | public class Tuple3 { 4 | A va; 5 | B vb; 6 | C vc; 7 | 8 | public Tuple3(A a, B b, C c) { 9 | va=a; 10 | vb=b; 11 | vc=c; 12 | } 13 | public A _1(){ 14 | return va; 15 | } 16 | 17 | public B _2(){ 18 | return vb; 19 | } 20 | 21 | public C _3(){ 22 | return vc; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /libcocoainput/darwin/libcocoainput/Logger.h: -------------------------------------------------------------------------------- 1 | // 2 | // Logger.h 3 | // libcocoainput 4 | // 5 | // Created by Axer on 2019/03/23. 6 | // Copyright © 2019年 Axer. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | typedef void (*LogFunction)(const char*); 12 | 13 | void initLogPointer(LogFunction log,LogFunction error,LogFunction debug); 14 | 15 | void CILog(NSString* msg); 16 | void CIError(NSString* msg); 17 | void CIDebug(NSString* msg); 18 | -------------------------------------------------------------------------------- /fabric/gradle.properties: -------------------------------------------------------------------------------- 1 | # Done to increase the memory available to gradle. 2 | org.gradle.jvmargs=-Xmx1G 3 | 4 | # Fabric Properties 5 | # check these on https://fabricmc.net/use 6 | minecraft_version=1.18 7 | yarn_mappings=1.18+build.1 8 | loader_version=0.12.8 9 | 10 | # Mod Properties 11 | mod_version = 4.0.4 12 | maven_group = jp.axer.cocoainput 13 | archives_base_name = CocoaInput-1.18-fabric 14 | 15 | # Dependencies 16 | fabric_version=0.44.0+1.18 17 | modmenu_version=3.0.0 18 | -------------------------------------------------------------------------------- /src/fabric/java/jp/axer/cocoainput/loader/CocoaInputModMenu.java: -------------------------------------------------------------------------------- 1 | package jp.axer.cocoainput.loader; 2 | 3 | 4 | import com.terraformersmc.modmenu.api.ModMenuApi; 5 | import com.terraformersmc.modmenu.api.ConfigScreenFactory; 6 | import jp.axer.cocoainput.util.FCConfig; 7 | 8 | public class CocoaInputModMenu implements ModMenuApi { 9 | 10 | @Override 11 | public ConfigScreenFactory getModConfigScreenFactory() { 12 | return parent -> (new FCConfig().getScreen(parent)); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /libcocoainput/darwin/libcocoainput.xcodeproj/xcuserdata/axer.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | libcocoainput.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/main/java/jp/axer/cocoainput/util/ConfigPack.java: -------------------------------------------------------------------------------- 1 | package jp.axer.cocoainput.util; 2 | 3 | public interface ConfigPack { 4 | 5 | public static ConfigPack defaultConfig = new ConfigPack() { 6 | @Override 7 | public boolean isAdvancedPreeditDraw() { 8 | return true; 9 | } 10 | @Override 11 | public boolean isNativeCharTyped() { 12 | return true; 13 | } 14 | }; 15 | 16 | public boolean isAdvancedPreeditDraw(); 17 | public boolean isNativeCharTyped(); 18 | } 19 | -------------------------------------------------------------------------------- /libcocoainput/x11/Makefile: -------------------------------------------------------------------------------- 1 | CC = gcc 2 | CFLAGS = -Wall -fPIC 3 | FFLAGS = -lX11 4 | OBJS = libx11cocoainput.o logger.o 5 | LIBS = 6 | TARGET = libx11cocoainput.so 7 | DISTDIR = ../../src/main/resources/x11/ 8 | RM = rm 9 | CP = cp 10 | 11 | all: $(TARGET) 12 | 13 | install: $(TARGET) 14 | $(CP) -f $(TARGET) $(DISTDIR) 15 | 16 | $(TARGET): $(OBJS) 17 | $(CC) $(OBJS) $(CFLAGS) $(FFLAGS) $(LIBS) -shared -o $@ 18 | 19 | .c.o: 20 | $(CC) $(CFLAGS) $(LIBS) -c $< 21 | 22 | clean: 23 | $(RM) -f $(TARGET) $(OBJS) 24 | -------------------------------------------------------------------------------- /libcocoainput/win/Makefile: -------------------------------------------------------------------------------- 1 | CC = gcc.exe 2 | CFLAGS = -Wall -fPIC 3 | FFLAGS = 4 | OBJS = libwincocoainput.o logger.o 5 | LIBS = 6 | TARGET = libwincocoainput.dll 7 | DISTDIR = ../../src/main/resources/win/ 8 | RM = rm 9 | CP = cp 10 | 11 | all: $(TARGET) 12 | 13 | install: $(TARGET) 14 | $(CP) -f $(TARGET) $(DISTDIR) 15 | 16 | $(TARGET): $(OBJS) 17 | $(CC) $(CFLAGS) $(FFLAGS) $(LIBS) -shared -o $@ $(OBJS) -limm32 18 | 19 | .c.o: 20 | $(CC) $(CFLAGS) $(LIBS) -c $< 21 | 22 | clean: 23 | $(RM) -f $(TARGET) $(OBJS) 24 | -------------------------------------------------------------------------------- /libcocoainput/darwin/libcocoainput/MinecraftView.h: -------------------------------------------------------------------------------- 1 | // 2 | // MinecraftView.h 3 | // libcocoainput 4 | // 5 | // Created by Axer on 2019/03/23. 6 | // Copyright © 2019年 Axer. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @interface MinecraftView : NSObject 13 | @property void (*insertText)(const char*, const int, const int); 14 | @property void (*setMarkedText)(const char*, const int, const int, const int, const int); 15 | @property float* (*firstRectForCharacterRange)(void); 16 | @end 17 | -------------------------------------------------------------------------------- /src/main/java/jp/axer/cocoainput/arch/dummy/DummyIMEOperator.java: -------------------------------------------------------------------------------- 1 | 2 | package jp.axer.cocoainput.arch.dummy; 3 | 4 | 5 | import jp.axer.cocoainput.plugin.IMEOperator; 6 | 7 | public class DummyIMEOperator implements IMEOperator { 8 | 9 | @Override 10 | public void setFocused(boolean inFocused) { 11 | // TODO 自動生成されたメソッド・スタブ 12 | 13 | } 14 | 15 | @Override 16 | public void discardMarkedText() { 17 | // TODO 自動生成されたメソッド・スタブ 18 | 19 | } 20 | 21 | @Override 22 | public void removeInstance() { 23 | // TODO 自動生成されたメソッド・スタブ 24 | 25 | } 26 | 27 | } -------------------------------------------------------------------------------- /libcocoainput/darwin/libcocoainput/Makefile: -------------------------------------------------------------------------------- 1 | CC = gcc 2 | CFLAGS = -Wall -fobjc-arc -mmacosx-version-min=10.10 3 | FFLAGS = -framework Foundation -framework Cocoa 4 | OBJS = cocoainput.o Logger.o DataManager.o MinecraftView.o 5 | LIBS = 6 | TARGET = libcocoainput.dylib 7 | DISTDIR = ../../../src/main/resources/darwin/ 8 | RM = rm 9 | CP = cp 10 | 11 | all: $(TARGET) 12 | 13 | install: $(TARGET) 14 | $(CP) -f $(TARGET) $(DISTDIR) 15 | 16 | $(TARGET): $(OBJS) 17 | $(CC) $(CFLAGS) $(FFLAGS) $(LIBS) -shared -o $@ $(OBJS) 18 | 19 | .c.o: 20 | $(CC) $(CFLAGS) $(LIBS) -c $< 21 | 22 | clean: 23 | $(RM) -f $(TARGET) $(OBJS) 24 | -------------------------------------------------------------------------------- /src/main/java/jp/axer/cocoainput/mixin/SharedConstantsMixin.java: -------------------------------------------------------------------------------- 1 | package jp.axer.cocoainput.mixin; 2 | 3 | import org.spongepowered.asm.mixin.Mixin; 4 | import org.spongepowered.asm.mixin.Overwrite; 5 | 6 | import net.minecraft.SharedConstants; 7 | 8 | 9 | @Mixin(SharedConstants.class) 10 | public class SharedConstantsMixin { 11 | //@ModifyConstant(method="isAllowedChatCharacter",constant=@Constant(intValue=167)) 12 | //@Inject(at=@At("HEAD"),method="isAllowedChatCharacter") 13 | @Overwrite 14 | public static boolean isAllowedChatCharacter(char p) { 15 | return p>=' '&&p!=127; 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | ** Describe the bug ** 11 | 12 | ** Describe the environment ** 13 | - OS: [e.g. Ubuntu 18.04lts] 14 | - Arch: [e.g. x86_64] 15 | - IME: [e.g. fcitx/mozc] 16 | - Minecraft [e.g. 1.12] 17 | - ModVersion [e.g. 4.0.0] 18 | - ModSetting [ look curseforge] 19 | 20 | 21 | **To Reproduce** 22 | Steps to reproduce the behavior: 23 | 1. Go to '...' 24 | 2. Click on '....' 25 | 3. Scroll down to '....' 26 | 4. See error 27 | 28 | **Logs(URL)** 29 | No logs no solutions 30 | 31 | **Additional context** 32 | Add any other context about the problem here. 33 | -------------------------------------------------------------------------------- /src/main/java/jp/axer/cocoainput/util/Rect.java: -------------------------------------------------------------------------------- 1 | package jp.axer.cocoainput.util; 2 | 3 | public class Rect { 4 | private float x; 5 | private float y; 6 | private float height; 7 | private float width; 8 | 9 | public Rect(float x, float y, float width, float height) { 10 | this.x = x; 11 | this.y = y; 12 | this.height = height; 13 | this.width = width; 14 | } 15 | 16 | public float getX() { 17 | return this.x; 18 | } 19 | 20 | public float getY() { 21 | return this.y; 22 | } 23 | 24 | public float getWidth() { 25 | return this.width; 26 | } 27 | 28 | public float getHeight() { 29 | return this.height; 30 | } 31 | } -------------------------------------------------------------------------------- /src/fabric/java/jp/axer/cocoainput/mixin/MinecraftMixin.java: -------------------------------------------------------------------------------- 1 | package jp.axer.cocoainput.mixin; 2 | 3 | import org.spongepowered.asm.mixin.Mixin; 4 | import org.spongepowered.asm.mixin.injection.At; 5 | import org.spongepowered.asm.mixin.injection.Inject; 6 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 7 | 8 | import jp.axer.cocoainput.loader.FabricLoader; 9 | import net.minecraft.client.Minecraft; 10 | import net.minecraft.client.gui.screens.Screen; 11 | 12 | @Mixin(Minecraft.class) 13 | public class MinecraftMixin { 14 | @Inject(method="setScreen",at=@At("HEAD")) 15 | private void setScreen(Screen screen,CallbackInfo ci) { 16 | FabricLoader.instance.onChangeScreen(screen); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/jp/axer/cocoainput/util/ModLogger.java: -------------------------------------------------------------------------------- 1 | package jp.axer.cocoainput.util; 2 | 3 | import org.apache.logging.log4j.Level; 4 | import org.apache.logging.log4j.LogManager; 5 | 6 | public class ModLogger { 7 | public static boolean debugMode=true; 8 | 9 | public static void log(String msg,Object...data){ 10 | LogManager.getLogger("CocoaInput:Java").log( Level.INFO,msg, data); 11 | } 12 | 13 | public static void error(String msg,Object...data){ 14 | LogManager.getLogger("CocoaInput:Java").error(msg, data); 15 | } 16 | 17 | public static void debug(String msg,Object...data){ 18 | if(debugMode){ 19 | LogManager.getLogger("CocoaInput:Java").debug(msg, data); 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /src/main/java/jp/axer/cocoainput/arch/dummy/DummyController.java: -------------------------------------------------------------------------------- 1 | package jp.axer.cocoainput.arch.dummy; 2 | 3 | import jp.axer.cocoainput.plugin.CocoaInputController; 4 | import jp.axer.cocoainput.plugin.IMEOperator; 5 | import jp.axer.cocoainput.plugin.IMEReceiver; 6 | import jp.axer.cocoainput.util.ModLogger; 7 | import net.minecraft.client.gui.screens.Screen; 8 | 9 | public class DummyController implements CocoaInputController{ 10 | public DummyController() { 11 | ModLogger.log("This is a dummy controller."); 12 | } 13 | 14 | @Override 15 | public IMEOperator generateIMEOperator(IMEReceiver ime) { 16 | return new DummyIMEOperator(); 17 | } 18 | 19 | @Override 20 | public void screenOpenNotify(Screen sc) { 21 | // TODO 自動生成されたメソッド・スタブ 22 | 23 | } 24 | } -------------------------------------------------------------------------------- /src/main/java/jp/axer/cocoainput/util/FCConfig.java: -------------------------------------------------------------------------------- 1 | package jp.axer.cocoainput.util; 2 | 3 | import jp.axer.cocoainput.util.ConfigPack; 4 | 5 | public class FCConfig extends TinyConfig implements ConfigPack{ 6 | 7 | @Entry(comment="AdvancedPreeditDraw - Is preedit marking - Default:true") 8 | public static boolean advancedPreeditDraw=true; 9 | @Entry(comment="NativeCharTyped - Is text inserted with native way - Default:true") 10 | public static boolean nativeCharTyped=true; 11 | 12 | 13 | 14 | @Override 15 | public boolean isAdvancedPreeditDraw() { 16 | // TODO 自動生成されたメソッド・スタブ 17 | return advancedPreeditDraw; 18 | } 19 | @Override 20 | public boolean isNativeCharTyped() { 21 | // TODO 自動生成されたメソッド・スタブ 22 | return nativeCharTyped; 23 | } 24 | 25 | 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/jp/axer/cocoainput/arch/darwin/Handle.java: -------------------------------------------------------------------------------- 1 | package jp.axer.cocoainput.arch.darwin; 2 | 3 | import jp.axer.cocoainput.arch.darwin.CallbackFunction.*; 4 | import com.sun.jna.Callback; 5 | import com.sun.jna.Library; 6 | import com.sun.jna.Native; 7 | 8 | public interface Handle extends Library{ 9 | Handle INSTANCE=(Handle)Native.loadLibrary("cocoainput", Handle.class); 10 | 11 | 12 | void initialize(Callback log,Callback error,Callback debug); 13 | void refreshInstance(); 14 | void addInstance(String uuid, Func_insertText insertText_p, Func_setMarkedText setMarkedText_p, Func_firstRectForCharacterRange firstRectForCharacterRange_p); 15 | void removeInstance(String uuid); 16 | void discardMarkedText(String uuid); 17 | void setIfReceiveEvent(String uuid,int yn); 18 | float invertYCoordinate(float y); 19 | } -------------------------------------------------------------------------------- /libcocoainput/darwin/libcocoainput/Logger.m: -------------------------------------------------------------------------------- 1 | // 2 | // Logger.m 3 | // libcocoainput 4 | // 5 | // Created by Axer on 2019/03/23. 6 | // Copyright © 2019年 Axer. All rights reserved. 7 | // 8 | 9 | #import "Logger.h" 10 | 11 | struct { 12 | LogFunction log; 13 | LogFunction error; 14 | LogFunction debug; 15 | } LogPointer; 16 | 17 | void CILog(NSString* msg) { 18 | LogPointer.log([msg cStringUsingEncoding:NSUTF8StringEncoding]); 19 | } 20 | void CIError(NSString* msg) { 21 | LogPointer.error([msg cStringUsingEncoding:NSUTF8StringEncoding]); 22 | } 23 | void CIDebug(NSString* msg) { 24 | LogPointer.debug([msg cStringUsingEncoding:NSUTF8StringEncoding]); 25 | } 26 | 27 | void initLogPointer(LogFunction log,LogFunction error,LogFunction debug) { 28 | LogPointer.log = log; 29 | LogPointer.error = error; 30 | LogPointer.debug = debug; 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/jp/axer/cocoainput/util/PreeditFormatter.java: -------------------------------------------------------------------------------- 1 | package jp.axer.cocoainput.util; 2 | 3 | public class PreeditFormatter { 4 | public static final char SECTION = 167; // avoid shift-jis bug... 5 | 6 | public static Tuple3 formatMarkedText(String aString, int position1, int length1) {//ユーティリティ 7 | StringBuilder builder = new StringBuilder(aString); 8 | boolean hasCaret = length1 == 0; 9 | if (!hasCaret) {//主文節がある 10 | builder.insert(position1 + length1, SECTION+"r"+SECTION+"n");//主文節の終わりで修飾をリセットして下線修飾をセット 11 | builder.insert(position1, SECTION+"l");//主文節の始まりで太字修飾を追加 12 | } else {//主文説がない(キャレットが存在するのでそれを意識する) 13 | builder.insert(position1, SECTION+"r"+SECTION+"n"); 14 | } 15 | builder.insert(0, SECTION+"r"+SECTION+"n");//最初に下線修飾をセット 16 | builder.append(SECTION+"r");//最後に修飾をリセット 17 | return new Tuple3(new String(builder), position1, hasCaret); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/jp/axer/cocoainput/arch/x11/Handle.java: -------------------------------------------------------------------------------- 1 | package jp.axer.cocoainput.arch.x11; 2 | 3 | import com.sun.jna.Callback; 4 | import com.sun.jna.Library; 5 | import com.sun.jna.Native; 6 | import com.sun.jna.Pointer; 7 | import com.sun.jna.WString; 8 | 9 | public interface Handle extends Library{ 10 | Handle INSTANCE = (Handle)Native.loadLibrary("x11cocoainput", Handle.class); 11 | 12 | void set_focus(int flag); 13 | void initialize( 14 | long window, 15 | long xw, 16 | DrawCallback paramDrawCallback, 17 | DoneCallback paramDoneCallback, 18 | Callback log, 19 | Callback error, 20 | Callback debug 21 | ); 22 | 23 | public static interface DrawCallback extends Callback { 24 | Pointer invoke(int param1Int1, int param1Int2, int param1Int3, short param1Short, boolean param1Boolean, String param1String, WString param1WString, int param1Int4, int param1Int5, int param1Int6); 25 | } 26 | public static interface DoneCallback extends Callback { 27 | void invoke(); 28 | } 29 | 30 | 31 | } 32 | -------------------------------------------------------------------------------- /src/fabric/resources/fabric.mod.json: -------------------------------------------------------------------------------- 1 | { 2 | "schemaVersion": 1, 3 | "id": "cocoainput", 4 | "version": "${version}", 5 | 6 | "name": "CocoaInput", 7 | "description": "This is an example description! Tell everyone what your mod is about!", 8 | "authors": [ 9 | "Axeryok" 10 | ], 11 | "contact": { 12 | "homepage": "https://fabricmc.net/", 13 | "sources": "https://github.com/FabricMC/fabric-example-mod" 14 | }, 15 | 16 | "license": "MMPLJ", 17 | "icon": "assets/modid/icon.png", 18 | 19 | "environment": "*", 20 | "entrypoints": { 21 | "client": [ 22 | "jp.axer.cocoainput.loader.FabricLoader" 23 | ], 24 | "modmenu":[ 25 | "jp.axer.cocoainput.loader.CocoaInputModMenu" 26 | ] 27 | }, 28 | 29 | "depends": { 30 | "fabricloader": ">=0.11.3", 31 | "minecraft": ">=1.18", 32 | "java": ">=16" 33 | }, 34 | "suggests": { 35 | "another-mod": "*" 36 | }, 37 | "accessWidener":"cocoainput.accesswidener", 38 | "mixins": [ 39 | "cocoainput.mixins.json", 40 | "cocoafab.mixins.json" 41 | ] 42 | } 43 | -------------------------------------------------------------------------------- /libcocoainput/darwin/libcocoainput/cocoainput.h: -------------------------------------------------------------------------------- 1 | // 2 | // cocoainput.h 3 | // libcocoainput 4 | // 5 | // Created by Axer on 2019/03/23. 6 | // Copyright © 2019年 Axer. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "Logger.h" 12 | 13 | 14 | void initialize(LogFunction log,LogFunction error,LogFunction debug); 15 | void replaceInstanceMethod(Class cls, SEL sel, SEL renamedSel, Class dataCls); 16 | 17 | void addInstance(const char* uuid, 18 | void (*insertText_p)(const char*, const int, const int), 19 | void (*setMarkedText_p)(const char*, 20 | const int, 21 | const int, 22 | const int, 23 | const int), 24 | float* (*firstRectForCharacterRange)(void)); 25 | void removeInstance(const char* uuid); 26 | void refreshInstance(void); 27 | 28 | void discardMarkedText(const char* uuid); 29 | void setIfReceiveEvent(const char* uuid, int yn); 30 | -------------------------------------------------------------------------------- /libcocoainput/win/logger.c: -------------------------------------------------------------------------------- 1 | #define _GNU_SOURCE 2 | 3 | #include "logger.h" 4 | #include 5 | #include 6 | 7 | struct { 8 | LogFunction log; 9 | LogFunction error; 10 | LogFunction debug; 11 | } LogPointer; 12 | 13 | void CILog(const char* format,...) { 14 | char *msg; 15 | va_list args; 16 | va_start(args,format); 17 | vasprintf(&msg,format,args); 18 | LogPointer.log(msg); 19 | free(msg); 20 | va_end(args); 21 | } 22 | 23 | 24 | void CIError(const char* format,...) { 25 | char *msg; 26 | va_list args; 27 | va_start(args,format); 28 | vasprintf(&msg,format,args); 29 | LogPointer.error(msg); 30 | free(msg); 31 | va_end(args); 32 | } 33 | 34 | 35 | void CIDebug(const char* format,...) { 36 | char *msg; 37 | va_list args; 38 | va_start(args,format); 39 | vasprintf(&msg,format,args); 40 | LogPointer.debug(msg); 41 | free(msg); 42 | va_end(args); 43 | } 44 | 45 | 46 | 47 | void initLogPointer(LogFunction log,LogFunction error,LogFunction debug) { 48 | LogPointer.log = log; 49 | LogPointer.error = error; 50 | LogPointer.debug = debug; 51 | } 52 | -------------------------------------------------------------------------------- /libcocoainput/x11/logger.c: -------------------------------------------------------------------------------- 1 | #define _GNU_SOURCE 2 | 3 | #include "logger.h" 4 | #include 5 | #include 6 | 7 | struct { 8 | LogFunction log; 9 | LogFunction error; 10 | LogFunction debug; 11 | } LogPointer; 12 | 13 | void CILog(const char* format,...) { 14 | char *msg; 15 | va_list args; 16 | va_start(args,format); 17 | vasprintf(&msg,format,args); 18 | LogPointer.log(msg); 19 | free(msg); 20 | va_end(args); 21 | } 22 | 23 | 24 | void CIError(const char* format,...) { 25 | char *msg; 26 | va_list args; 27 | va_start(args,format); 28 | vasprintf(&msg,format,args); 29 | LogPointer.error(msg); 30 | free(msg); 31 | va_end(args); 32 | } 33 | 34 | 35 | void CIDebug(const char* format,...) { 36 | char *msg; 37 | va_list args; 38 | va_start(args,format); 39 | vasprintf(&msg,format,args); 40 | LogPointer.debug(msg); 41 | free(msg); 42 | va_end(args); 43 | } 44 | 45 | 46 | 47 | void initLogPointer(LogFunction log,LogFunction error,LogFunction debug) { 48 | LogPointer.log = log; 49 | LogPointer.error = error; 50 | LogPointer.debug = debug; 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/jp/axer/cocoainput/mixin/SignEditScreenMixin.java: -------------------------------------------------------------------------------- 1 | package jp.axer.cocoainput.mixin; 2 | 3 | import org.objectweb.asm.Opcodes; 4 | import org.spongepowered.asm.mixin.Mixin; 5 | import org.spongepowered.asm.mixin.injection.At; 6 | import org.spongepowered.asm.mixin.injection.Inject; 7 | import org.spongepowered.asm.mixin.injection.Redirect; 8 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 9 | 10 | import jp.axer.cocoainput.wrapper.SignEditScreenWrapper; 11 | import net.minecraft.client.gui.screens.inventory.SignEditScreen; 12 | 13 | @Mixin(SignEditScreen.class) 14 | public class SignEditScreenMixin { 15 | SignEditScreenWrapper wrapper; 16 | 17 | @Inject(method="init",at=@At("RETURN")) 18 | private void init(CallbackInfo ci) { 19 | wrapper = new SignEditScreenWrapper((SignEditScreen)(Object)this); 20 | } 21 | 22 | @Redirect(method="tick",at = @At(value="FIELD", target="Lnet/minecraft/client/gui/screens/inventory/SignEditScreen;frame:I",opcode=Opcodes.PUTFIELD)) 23 | private void injectCurosr(SignEditScreen esc,int n) { 24 | esc.frame=wrapper.renewCursorCounter(); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/jp/axer/cocoainput/mixin/BookEditScreenMixin.java: -------------------------------------------------------------------------------- 1 | package jp.axer.cocoainput.mixin; 2 | 3 | import org.objectweb.asm.Opcodes; 4 | import org.spongepowered.asm.mixin.Mixin; 5 | import org.spongepowered.asm.mixin.injection.At; 6 | import org.spongepowered.asm.mixin.injection.Inject; 7 | import org.spongepowered.asm.mixin.injection.Redirect; 8 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 9 | 10 | import jp.axer.cocoainput.wrapper.BookEditScreenWrapper; 11 | import net.minecraft.client.gui.screens.inventory.BookEditScreen; 12 | 13 | @Mixin(BookEditScreen.class) 14 | public class BookEditScreenMixin { 15 | BookEditScreenWrapper wrapper; 16 | 17 | @Inject(method="init*",at=@At("RETURN")) 18 | private void init(CallbackInfo ci) { 19 | wrapper = new BookEditScreenWrapper((BookEditScreen)(Object)this); 20 | } 21 | 22 | @Redirect(method="tick",at = @At(value="FIELD", target="Lnet/minecraft/client/gui/screens/inventory/BookEditScreen;frameTick:I",opcode=Opcodes.PUTFIELD)) 23 | private void injectCurosr(BookEditScreen esc,int n) { 24 | esc.frameTick=wrapper.renewCursorCounter(); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/jp/axer/cocoainput/arch/win/WinIMEOperator.java: -------------------------------------------------------------------------------- 1 | package jp.axer.cocoainput.arch.win; 2 | 3 | import jp.axer.cocoainput.plugin.IMEOperator; 4 | import jp.axer.cocoainput.plugin.IMEReceiver; 5 | 6 | public class WinIMEOperator implements IMEOperator { 7 | public IMEReceiver owner; 8 | private boolean focus=false; 9 | public WinIMEOperator(IMEReceiver op) { 10 | this.owner=op; 11 | } 12 | 13 | @Override 14 | public void discardMarkedText() { 15 | // TODO Auto-generated method stub 16 | 17 | } 18 | 19 | @Override 20 | public void removeInstance() { 21 | // TODO Auto-generated method stub 22 | 23 | } 24 | 25 | @Override 26 | public void setFocused(boolean arg0) { 27 | // TODO Auto-generated method stub 28 | if(arg0==focus) { 29 | return ; 30 | } 31 | focus=arg0; 32 | Logger.log("setFocusedCalled "+ arg0); 33 | if(arg0) { 34 | WinController.focusedOperator=this; 35 | Handle.INSTANCE.set_focus(1); 36 | } 37 | else { 38 | if(WinController.focusedOperator==this) { 39 | owner.insertText("", 0, 0); 40 | WinController.focusedOperator=null; 41 | Handle.INSTANCE.set_focus(0); 42 | } 43 | } 44 | 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/jp/axer/cocoainput/mixin/EditBoxMixin.java: -------------------------------------------------------------------------------- 1 | package jp.axer.cocoainput.mixin; 2 | 3 | import org.spongepowered.asm.mixin.Mixin; 4 | import org.spongepowered.asm.mixin.injection.At; 5 | import org.spongepowered.asm.mixin.injection.Inject; 6 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 7 | 8 | import jp.axer.cocoainput.wrapper.EditBoxWrapper; 9 | import net.minecraft.client.gui.components.EditBox; 10 | 11 | @Mixin(EditBox.class) 12 | public class EditBoxMixin { 13 | EditBoxWrapper wrapper; 14 | 15 | @Inject(method="*",at=@At("RETURN")) 16 | private void init(CallbackInfo ci) { 17 | wrapper = new EditBoxWrapper((EditBox)(Object)this); 18 | } 19 | 20 | @Inject(method="setFocus",at=@At("HEAD")) 21 | private void setFocus(boolean b,CallbackInfo ci) { 22 | wrapper.setFocused(b); 23 | } 24 | @Inject(method="setCanLoseFocus",at=@At("HEAD")) 25 | private void setCanLoseFocus(boolean b,CallbackInfo ci) { 26 | wrapper.setCanLoseFocus(b); 27 | } 28 | @Inject(method="tick",at=@At("HEAD"),cancellable=true) 29 | private void tick(CallbackInfo ci) { 30 | wrapper.updateCursorCounter(); 31 | ci.cancel(); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/jp/axer/cocoainput/arch/x11/X11IMEOperator.java: -------------------------------------------------------------------------------- 1 | package jp.axer.cocoainput.arch.x11; 2 | 3 | import jp.axer.cocoainput.plugin.IMEOperator; 4 | import jp.axer.cocoainput.plugin.IMEReceiver; 5 | 6 | public class X11IMEOperator implements IMEOperator { 7 | public IMEReceiver owner; 8 | private boolean focus=false; 9 | public X11IMEOperator(IMEReceiver op) { 10 | this.owner=op; 11 | } 12 | 13 | @Override 14 | public void discardMarkedText() { 15 | // TODO Auto-generated method stub 16 | 17 | } 18 | 19 | @Override 20 | public void removeInstance() { 21 | // TODO Auto-generated method stub 22 | 23 | } 24 | 25 | @Override 26 | public void setFocused(boolean arg0) { 27 | // TODO Auto-generated method stub 28 | if(arg0==focus) { 29 | return ; 30 | } 31 | focus=arg0; 32 | Logger.log("setFocusedCalled "+ arg0); 33 | if(arg0) { 34 | X11Controller.focusedOperator=this; 35 | Handle.INSTANCE.set_focus(1); 36 | } 37 | else { 38 | if(X11Controller.focusedOperator==this) { 39 | owner.insertText("", 0, 0); 40 | X11Controller.focusedOperator=null; 41 | Handle.INSTANCE.set_focus(0); 42 | X11Controller.setupKeyboardEvent(); 43 | } 44 | } 45 | 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/jp/axer/cocoainput/arch/win/Handle.java: -------------------------------------------------------------------------------- 1 | package jp.axer.cocoainput.arch.win; 2 | 3 | import com.sun.jna.Callback; 4 | import com.sun.jna.Library; 5 | import com.sun.jna.Native; 6 | import com.sun.jna.Pointer; 7 | import com.sun.jna.WString; 8 | 9 | public interface Handle extends Library{ 10 | Handle INSTANCE = (Handle)Native.loadLibrary("libwincocoainput", Handle.class); 11 | 12 | void set_focus(int flag); 13 | void initialize( 14 | long window, 15 | PreeditCallback paramDrawCallback, 16 | DoneCallback paramDoneCallback, 17 | RectCallback paramRectCallback, 18 | Callback log, 19 | Callback error, 20 | Callback debug 21 | ); 22 | 23 | public static interface PreeditCallback extends Callback{ 24 | void invoke(WString str,int cursor,int length); 25 | } 26 | /*public static interface DrawCallback extends Callback { 27 | Pointer invoke(int param1Int1, int param1Int2, int param1Int3, short param1Short, boolean param1Boolean, String param1String, WString param1WString, int param1Int4, int param1Int5, int param1Int6); 28 | }*/ 29 | public static interface DoneCallback extends Callback { 30 | void invoke(WString str); 31 | } 32 | 33 | public static interface RectCallback extends Callback{ 34 | int invoke(Pointer p); 35 | } 36 | 37 | 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/jp/axer/cocoainput/arch/win/Logger.java: -------------------------------------------------------------------------------- 1 | package jp.axer.cocoainput.arch.win; 2 | 3 | import org.apache.logging.log4j.Level; 4 | import org.apache.logging.log4j.LogManager; 5 | 6 | import com.sun.jna.Callback; 7 | 8 | public class Logger { 9 | 10 | public static void log(String msg,Object...data){ 11 | LogManager.getLogger("CocoaInputWin:Java").log( Level.INFO,msg, data); 12 | } 13 | 14 | public static void error(String msg,Object...data){ 15 | LogManager.getLogger("CocoaInputWin:Java").log( Level.ERROR,msg, data); 16 | } 17 | 18 | public static void debug(String msg,Object...data){ 19 | LogManager.getLogger("CocoaInputWin:Java").log( Level.DEBUG,msg, data); 20 | 21 | } 22 | 23 | public static Callback clangLog = new Callback() { 24 | public void invoke(String msg) { 25 | LogManager.getLogger("CocoaInputWin:Clang").log(Level.INFO, msg); 26 | } 27 | }; 28 | public static Callback clangError = new Callback() { 29 | public void invoke(String msg) { 30 | LogManager.getLogger("CocoaInputWin:Clang").log(Level.ERROR, msg); 31 | } 32 | }; 33 | public static Callback clangDebug = new Callback() { 34 | public void invoke(String msg) { 35 | LogManager.getLogger("CocoaInputWin:Clang").log(Level.DEBUG, msg); 36 | } 37 | }; 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/jp/axer/cocoainput/arch/x11/Logger.java: -------------------------------------------------------------------------------- 1 | package jp.axer.cocoainput.arch.x11; 2 | 3 | import org.apache.logging.log4j.Level; 4 | import org.apache.logging.log4j.LogManager; 5 | 6 | import com.sun.jna.Callback; 7 | 8 | public class Logger { 9 | 10 | public static void log(String msg,Object...data){ 11 | LogManager.getLogger("CocoaInputX11:Java").log( Level.INFO,msg, data); 12 | } 13 | 14 | public static void error(String msg,Object...data){ 15 | LogManager.getLogger("CocoaInputX11:Java").log( Level.ERROR,msg, data); 16 | } 17 | 18 | public static void debug(String msg,Object...data){ 19 | LogManager.getLogger("CocoaInputX11:Java").log( Level.DEBUG,msg, data); 20 | 21 | } 22 | 23 | public static Callback clangLog = new Callback() { 24 | public void invoke(String msg) { 25 | LogManager.getLogger("CocoaInputX11:Clang").log(Level.INFO, msg); 26 | } 27 | }; 28 | public static Callback clangError = new Callback() { 29 | public void invoke(String msg) { 30 | LogManager.getLogger("CocoaInputX11:Clang").log(Level.ERROR, msg); 31 | } 32 | }; 33 | public static Callback clangDebug = new Callback() { 34 | public void invoke(String msg) { 35 | LogManager.getLogger("CocoaInputX11:Clang").log(Level.DEBUG, msg); 36 | } 37 | }; 38 | } 39 | -------------------------------------------------------------------------------- /src/fabric/java/jp/axer/cocoainput/loader/FabricLoader.java: -------------------------------------------------------------------------------- 1 | package jp.axer.cocoainput.loader; 2 | 3 | import net.fabricmc.api.ClientModInitializer; 4 | import net.fabricmc.fabric.api.client.screen.v1.ScreenEvents; 5 | import jp.axer.cocoainput.CocoaInput; 6 | import jp.axer.cocoainput.util.ModLogger; 7 | import jp.axer.cocoainput.util.FCConfig; 8 | import net.minecraft.client.gui.screens.Screen; 9 | 10 | public class FabricLoader implements ClientModInitializer { 11 | public static FabricLoader instance; 12 | public CocoaInput cocoainput; 13 | @Override 14 | public void onInitializeClient() { 15 | FabricLoader.instance=this; 16 | } 17 | public void onWindowLaunched(){ 18 | this.cocoainput=new CocoaInput("Fabric",null); 19 | ModLogger.log("Fabric config setup"); 20 | ModLogger.log("Config path:"+net.fabricmc.loader.api.FabricLoader.getInstance().getConfigDir().resolve("cocoainput.json").toString()); 21 | FCConfig.init("cocoainput",net.fabricmc.loader.api.FabricLoader.getInstance().getConfigDir().resolve("cocoainput.json"), FCConfig.class); 22 | CocoaInput.config=new FCConfig(); 23 | ModLogger.log("ConfigPack:"+CocoaInput.config.isAdvancedPreeditDraw()+" "+CocoaInput.config.isNativeCharTyped()); 24 | } 25 | 26 | public void onChangeScreen(Screen sc){ 27 | if(this.cocoainput==null){ 28 | this.onWindowLaunched(); 29 | return; 30 | } 31 | this.cocoainput.distributeScreen(sc); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/jp/axer/cocoainput/arch/darwin/DarwinController.java: -------------------------------------------------------------------------------- 1 | package jp.axer.cocoainput.arch.darwin; 2 | 3 | import java.lang.reflect.Field; 4 | 5 | import jp.axer.cocoainput.CocoaInput; 6 | import jp.axer.cocoainput.plugin.CocoaInputController; 7 | import jp.axer.cocoainput.plugin.IMEOperator; 8 | import jp.axer.cocoainput.plugin.IMEReceiver; 9 | import jp.axer.cocoainput.util.ModLogger; 10 | import net.minecraft.client.gui.screens.Screen; 11 | 12 | public class DarwinController implements CocoaInputController { 13 | public DarwinController() throws Exception { 14 | CocoaInput.copyLibrary("libcocoainput.dylib", "darwin/libcocoainput.dylib"); 15 | Handle.INSTANCE.initialize(CallbackFunction.Func_log, CallbackFunction.Func_error, CallbackFunction.Func_debug); 16 | ModLogger.log("DarwinController has been initialized."); 17 | } 18 | 19 | @Override 20 | public IMEOperator generateIMEOperator(IMEReceiver ime) { 21 | return new DarwinIMEOperator(ime); 22 | } 23 | 24 | 25 | @Override 26 | public void screenOpenNotify(Screen gui) { 27 | try { 28 | Field wrapper = gui.getClass().getField("wrapper"); 29 | wrapper.setAccessible(true); 30 | if (wrapper.get(gui) instanceof IMEReceiver) 31 | return; 32 | } catch (Exception e) {/* relax */} 33 | Handle.INSTANCE.refreshInstance();//GUIの切り替えでIMの使用をoffにする 34 | 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /README.MD: -------------------------------------------------------------------------------- 1 | # CocoaInput 2 | Support IME - Input Method Editor(Japanese,Chinese,Korean) in Minecraft on Multi-platforms(macOS, Windows, X11). 3 | 4 | ## Compiling 5 | 1. Clone git repository 6 | ```Bash 7 | git clone https://github.com/Axeryok/CocoaInput.git 8 | cd CocoaInput 9 | ``` 10 | 2. Compile native library
11 | CocoaInput needs native-platform libraries to work. 12 | To compile them, run one of below scripts which is your platform. 13 | - build_lib_for_mac.sh - For macOS 14 | - build_lib_for_x11.sh - For Linux 15 | - build_lib_for_win.sh - For Windows 16 | - (build_lib_all.sh - For all platform, You should create remote_build.sh to build macOS lib remotely.) 17 | 3. Compile Forge Mod
18 | Type below command.Forge mod will be located in "fabric/build/libs". 19 | ```Bash 20 | ./gradlew build 21 | ``` 22 | 4. Compile Fabric Mod
23 | Type below command.Fabric mod will be located in "fabric/build/libs". 24 | ```Bash 25 | cd fabric 26 | ./gradlew build 27 | ``` 28 | 29 | ## Installing 30 | CocoaInput official binaries has been distributed on https://www.curseforge.com/minecraft/mc-mods/cocoainput . 31 | Get jar from above URL or trying ”Compiling" task. 32 | Place it in your mods directory. 33 | 34 | CocoaInput requires MinecraftForge or Fabric. 35 | 36 | This mod uses Java Native Access (Apache Licence2) and binuary for Minecraft1.7.10 contains it. 37 | 38 | ## License 39 | Minecraft Mod Public License Japanese Transration 40 | -------------------------------------------------------------------------------- /libcocoainput/darwin/libcocoainput/DataManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // DataManager.h 3 | // libcocoainput 4 | // 5 | // Created by Axer on 2019/03/23. 6 | // Copyright © 2019年 Axer. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | #import "MinecraftView.h" 13 | 14 | @interface DataManager : NSObject 15 | 16 | @property BOOL hasPreeditText; 17 | @property BOOL isSentedInsertText; 18 | @property BOOL isBeforeActionSetMarkedText; 19 | //@property void (*insertText)(const char*, const int, const int); 20 | //@property void (*setMarkedText)(const char*, const int, const int, const int, const int); 21 | //@property float* (*firstRectForCharacterRange)(void); 22 | 23 | 24 | 25 | 26 | @property NSMutableDictionary* dic; 27 | @property MinecraftView* activeView; 28 | @property NSView* glfwView; 29 | + (instancetype)sharedManager; 30 | - (void) modifyGLFWView; 31 | 32 | //機能上書き 33 | - (void)keyDown:(NSEvent*)theEvent; 34 | - (void)interpretKeyEvents:(NSArray*)eventArray; 35 | 36 | //形式上 37 | - (void)org_keyDown:(NSEvent*)theEvent; 38 | - (void)org_unmarkText; 39 | - (void)org_interpretKeyEvents:(NSArray*)eventArray; 40 | - (NSRect)org_firstRectForCharacterRange:(NSRange)aRange 41 | actualRange:(NSRangePointer)actualRange; 42 | - (void)org_insertText:(id)aString replacementRange:(NSRange)replacementRange; 43 | - (void)org_setMarkedText:(id)aString 44 | selectedRange:(NSRange)selectedRange 45 | replacementRange:(NSRange)replacementRange ; 46 | @end 47 | -------------------------------------------------------------------------------- /src/main/java/jp/axer/cocoainput/arch/darwin/CallbackFunction.java: -------------------------------------------------------------------------------- 1 | package jp.axer.cocoainput.arch.darwin; 2 | 3 | import com.sun.jna.Callback; 4 | import com.sun.jna.Pointer; 5 | import jp.axer.cocoainput.util.ModLogger; 6 | import org.apache.logging.log4j.Level; 7 | import org.apache.logging.log4j.LogManager; 8 | 9 | public class CallbackFunction { 10 | //used to interact Objective-C code 11 | interface Func_insertText extends Callback { 12 | void invoke(String str, int position, int length); 13 | } 14 | 15 | interface Func_setMarkedText extends Callback { 16 | void invoke(String str, int position1, int length1, int position2, int length2); 17 | } 18 | 19 | interface Func_firstRectForCharacterRange extends Callback { 20 | Pointer invoke(); 21 | } 22 | 23 | //used to provide Objective-C with logging way 24 | public static Callback Func_log = new Callback() { 25 | public void invoke(String msg) { 26 | LogManager.getLogger("CocoaInput:ObjC").log(Level.INFO, msg); 27 | } 28 | }; 29 | public static Callback Func_error = new Callback() { 30 | public void invoke(String msg) { 31 | LogManager.getLogger("CocoaInput:ObjC").log(Level.ERROR, msg); 32 | } 33 | }; 34 | public static Callback Func_debug = new Callback() { 35 | public void invoke(String msg) { 36 | if (ModLogger.debugMode) { 37 | LogManager.getLogger("CocoaInput:ObjC").log(Level.DEBUG, msg); 38 | } 39 | } 40 | }; 41 | } -------------------------------------------------------------------------------- /libcocoainput/x11/libx11cocoainput.h: -------------------------------------------------------------------------------- 1 | //#include 2 | #include 3 | //#include "internal.h" 4 | //#include "x11_platform.h" 5 | #include 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #include "logger.h" 14 | 15 | typedef int GLFWbool; 16 | 17 | typedef struct _GLFWwindowX11 18 | { 19 | Colormap colormap; 20 | Window handle; 21 | //Window parent; 22 | XIC ic; 23 | 24 | GLFWbool overrideRedirect; 25 | GLFWbool iconified; 26 | GLFWbool maximized; 27 | 28 | // Whether the visual supports framebuffer transparency 29 | GLFWbool transparent; 30 | 31 | // Cached position and size used to filter out duplicate events 32 | int width, height; 33 | int xpos, ypos; 34 | 35 | // The last received cursor position, regardless of source 36 | int lastCursorPosX, lastCursorPosY; 37 | // The last position the cursor was warped to by GLFW 38 | int warpCursorPosX, warpCursorPosY; 39 | 40 | // The time of the last KeyPress event per keycode, for discarding 41 | // duplicate key events generated for some keys by ibus 42 | Time keyPressTimes[256]; 43 | 44 | } _GLFWwindowX11; 45 | 46 | 47 | void initialize( 48 | long waddr, 49 | long xw, 50 | int*(*c_draw)(int,int,int,short,int,char*,wchar_t*,int,int,int), 51 | void(*c_done)(), 52 | LogFunction log, 53 | LogFunction error, 54 | LogFunction debug 55 | ); 56 | 57 | 58 | 59 | 60 | void set_focus(int flag); 61 | -------------------------------------------------------------------------------- /src/forge/resources/META-INF/accesstransformer.cfg: -------------------------------------------------------------------------------- 1 | public net.minecraft.client.gui.components.EditBox f_94092_ #font 2 | public net.minecraft.client.gui.components.EditBox f_94096_ #bordered 3 | public net.minecraft.client.gui.components.EditBox f_94093_ #value 4 | public net.minecraft.client.gui.components.EditBox f_94095_ #frame 5 | public net.minecraft.client.gui.components.EditBox m_94174_(Ljava/lang/String;)V #onValueChange 6 | 7 | 8 | public net.minecraft.client.gui.screens.inventory.SignEditScreen f_99256_ #line 9 | public net.minecraft.client.gui.screens.inventory.SignEditScreen f_99254_ #sign 10 | public net.minecraft.client.gui.screens.inventory.SignEditScreen f_99258_ #messages 11 | public net.minecraft.client.gui.screens.inventory.SignEditScreen f_99257_ #signField 12 | public net.minecraft.client.gui.screens.inventory.SignEditScreen f_99255_ #frame 13 | 14 | 15 | public net.minecraft.client.gui.screens.inventory.BookEditScreen m_98158_(Ljava/lang/String;)V #setCurrentPage 16 | public net.minecraft.client.gui.screens.inventory.BookEditScreen m_98191_()Ljava.lang.String; #getCurrentPage 17 | public net.minecraft.client.gui.screens.inventory.BookEditScreen f_98071_ #title 18 | public net.minecraft.client.gui.screens.inventory.BookEditScreen f_98067_ #isSigning 19 | public net.minecraft.client.gui.screens.inventory.BookEditScreen f_98072_ #pageEdit 20 | public net.minecraft.client.gui.screens.inventory.BookEditScreen f_98073_ #titleEdit 21 | public net.minecraft.client.gui.screens.inventory.BookEditScreen f_98068_ #frameTick 22 | 23 | public net.minecraft.client.gui.screens.Screen f_96547_ #font 24 | 25 | public net.minecraft.client.KeyboardHandler m_90889_(JII)V #charTyped 26 | -------------------------------------------------------------------------------- /src/fabric/resources/cocoainput.accesswidener: -------------------------------------------------------------------------------- 1 | accessWidener v1 named 2 | accessible field net/minecraft/client/gui/components/EditBox font Lnet/minecraft/client/gui/Font; 3 | accessible field net/minecraft/client/gui/components/EditBox bordered Z 4 | accessible field net/minecraft/client/gui/components/EditBox value Ljava/lang/String; 5 | accessible field net/minecraft/client/gui/components/EditBox frame I 6 | accessible method net/minecraft/client/gui/components/EditBox onValueChange (Ljava/lang/String;)V 7 | accessible field net/minecraft/client/gui/screens/inventory/SignEditScreen line I 8 | accessible field net/minecraft/client/gui/screens/inventory/SignEditScreen frame I 9 | accessible field net/minecraft/client/gui/screens/inventory/SignEditScreen sign Lnet/minecraft/world/level/block/entity/SignBlockEntity; 10 | accessible field net/minecraft/client/gui/screens/inventory/SignEditScreen messages [Ljava/lang/String; 11 | accessible field net/minecraft/client/gui/screens/inventory/SignEditScreen signField Lnet/minecraft/client/gui/font/TextFieldHelper; 12 | accessible method net/minecraft/client/gui/screens/inventory/BookEditScreen setCurrentPageText (Ljava/lang/String;)V 13 | accessible method net/minecraft/client/gui/screens/inventory/BookEditScreen getCurrentPageText ()Ljava/lang/String; 14 | accessible field net/minecraft/client/gui/screens/inventory/BookEditScreen title Ljava/lang/String; 15 | accessible field net/minecraft/client/gui/screens/inventory/BookEditScreen isSigning Z 16 | accessible field net/minecraft/client/gui/screens/inventory/BookEditScreen frameTick I 17 | accessible field net/minecraft/client/gui/screens/inventory/BookEditScreen pageEdit Lnet/minecraft/client/gui/font/TextFieldHelper; 18 | accessible field net/minecraft/client/gui/screens/inventory/BookEditScreen titleEdit Lnet/minecraft/client/gui/font/TextFieldHelper; 19 | accessible field net/minecraft/client/gui/screens/Screen font Lnet/minecraft/client/gui/Font; 20 | accessible method net/minecraft/client/KeyboardHandler charTyped (JII)V 21 | -------------------------------------------------------------------------------- /src/forge/resources/META-INF/mods.toml: -------------------------------------------------------------------------------- 1 | # This is an example mods.toml file. It contains the data relating to the loading mods. 2 | # There are several mandatory fields (#mandatory), and many more that are optional (#optional). 3 | # The overall format is standard TOML format, v0.5.0. 4 | # Note that there are a couple of TOML lists in this file. 5 | # Find more information on toml format here: https://github.com/toml-lang/toml 6 | # The name of the mod loader type to load - for regular FML @Mod mods it should be javafml 7 | modLoader="javafml" #mandatory 8 | # A version range to match for said mod loader - for regular FML @Mod it will be the forge version 9 | loaderVersion="[25,)" #mandatory (24 is current forge version) 10 | # A URL to refer people to when problems occur with this mod 11 | issueTrackerURL="https://github.com/Axeryok/CocoaInput/issues" #optional 12 | # License 13 | license="Minecraft Mod Public License Japanese Transration" #mandatory 14 | # A list of mods - how many allowed here is determined by the individual mod loader 15 | [[mods]] #mandatory 16 | # The modid of the mod 17 | modId="cocoainput" #mandatory 18 | # The version number of the mod - there's a few well known ${} variables useable here or just hardcode it 19 | version="${file.jarVersion}" #mandatory 20 | # A display name for the mod 21 | displayName="CocoaInput" #mandatory 22 | # A URL to query for updates for this mod. See the JSON update specification 23 | #updateJSONURL="http://myurl.me/" #optional 24 | # A URL for the "homepage" for this mod, displayed in the mod UI 25 | displayURL="https://axer.jp/" #optional 26 | # A file name (in the root of the mod JAR) containing a logo for display 27 | #logoFile="logo.png" #optional 28 | # A text field displayed in the mod UI 29 | credits="This mod uses JavaNativeAccess(Apache License2)." #optional 30 | # A text field displayed in the mod UI 31 | authors="Axeryok" #optional 32 | # The description text for the mod (multi line!) (#mandatory) 33 | description=''' 34 | Support IME input on macOS,Windows,X11(Linux). 35 | ''' 36 | -------------------------------------------------------------------------------- /src/forge/java/jp/axer/cocoainput/loader/ForgeLoader.java: -------------------------------------------------------------------------------- 1 | package jp.axer.cocoainput.loader; 2 | 3 | import jp.axer.cocoainput.CocoaInput; 4 | import jp.axer.cocoainput.util.ModLogger; 5 | import jp.axer.cocoainput.util.FCConfig; 6 | import net.minecraftforge.client.event.ScreenOpenEvent; 7 | import net.minecraftforge.common.MinecraftForge; 8 | import net.minecraftforge.eventbus.api.SubscribeEvent; 9 | import net.minecraftforge.client.ConfigGuiHandler; 10 | 11 | import net.minecraftforge.fml.ModList; 12 | import net.minecraftforge.fml.ModLoadingContext; 13 | import net.minecraftforge.fml.common.Mod; 14 | import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent; 15 | import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; 16 | import net.minecraftforge.fml.loading.FMLPaths; 17 | 18 | @Mod("cocoainput") 19 | public class ForgeLoader { 20 | private CocoaInput instance; 21 | 22 | public ForgeLoader(){ 23 | FMLJavaModLoadingContext.get().getModEventBus().addListener(this::setup); 24 | MinecraftForge.EVENT_BUS.register(this); 25 | 26 | } 27 | 28 | private void setup(final FMLCommonSetupEvent event) { 29 | this.instance=new CocoaInput("MinecraftForge",ModList.get().getModFileById("cocoainput").getFile().getFilePath().toString()); 30 | ModLogger.log("Forge config setup"); 31 | ModLogger.log("Config path:"+FMLPaths.CONFIGDIR.get().resolve("cocoainput.json").toString()); 32 | FCConfig.init("cocoainput",FMLPaths.CONFIGDIR.get().resolve("cocoainput.json"), FCConfig.class); 33 | ModLoadingContext.get().registerExtensionPoint(ConfigGuiHandler.ConfigGuiFactory.class, ()->new ConfigGuiHandler.ConfigGuiFactory((mc,modListScreen)->new FCConfig().getScreen(modListScreen))); 34 | CocoaInput.config=new FCConfig(); 35 | ModLogger.log("ConfigPack:"+CocoaInput.config.isAdvancedPreeditDraw()+" "+CocoaInput.config.isNativeCharTyped()); 36 | } 37 | @SubscribeEvent 38 | public void didChangeGui(ScreenOpenEvent event) { 39 | this.instance.distributeScreen(event.getScreen()); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/jp/axer/cocoainput/wrapper/EditBoxWrapper.java: -------------------------------------------------------------------------------- 1 | 2 | package jp.axer.cocoainput.wrapper; 3 | 4 | import jp.axer.cocoainput.CocoaInput; 5 | import jp.axer.cocoainput.plugin.IMEOperator; 6 | import jp.axer.cocoainput.plugin.IMEReceiver; 7 | import jp.axer.cocoainput.util.ModLogger; 8 | import jp.axer.cocoainput.util.Rect; 9 | import net.minecraft.client.gui.components.EditBox; 10 | import net.minecraft.network.chat.TextComponent; 11 | 12 | public class EditBoxWrapper extends IMEReceiver { 13 | private IMEOperator myIME; 14 | private EditBox owner; 15 | 16 | public EditBoxWrapper(EditBox field) { 17 | ModLogger.debug("EditBox init: " + field.hashCode()); 18 | owner = field; 19 | myIME = CocoaInput.getController().generateIMEOperator(this); 20 | } 21 | 22 | public void setCanLoseFocus(boolean newParam) { 23 | if (!newParam) setFocused(true); 24 | } 25 | 26 | public void setFocused(boolean newParam) { 27 | owner.setFormatter( ((abc,def) -> new TextComponent(abc).getVisualOrderText() )); 28 | myIME.setFocused(newParam); 29 | } 30 | 31 | 32 | public void updateCursorCounter() { 33 | if (cursorVisible) owner.frame++; 34 | } 35 | 36 | protected void setText(String text) { 37 | owner.value=text; 38 | } 39 | 40 | protected String getText() { 41 | return owner.value; 42 | } 43 | 44 | protected void setCursorInvisible() { 45 | owner.frame=6; 46 | } 47 | 48 | protected int getCursorPos() { 49 | return owner.getCursorPosition(); 50 | } 51 | 52 | protected void setCursorPos(int p) { 53 | owner.moveCursorTo(p); 54 | } 55 | 56 | protected void setSelectionPos(int p) { 57 | owner.setHighlightPos(p); 58 | } 59 | 60 | 61 | @Override 62 | public Rect getRect() { 63 | return new Rect(//{x,y} 64 | (owner.font.width(owner.getValue().substring(0, originalCursorPosition)) + (owner.bordered ? owner.x + 4 : owner.x)), 65 | (owner.font.lineHeight + (owner.bordered ? owner.y + (owner.getHeight() - 8) / 2 : owner.y)), 66 | owner.getWidth(), 67 | owner.getHeight() 68 | 69 | ); 70 | } 71 | 72 | protected void notifyParent(String text) { 73 | // TODO 自動生成されたメソッド・スタブ 74 | owner.onValueChange(text); 75 | 76 | } 77 | 78 | 79 | } 80 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Minecraft Mod Public License Japanese Transration (MMPL_J) 2 | 3 | Version 1.0.1 4 | 5 | 6 | (A.序文) 7 | 8 | 一条 [MMPL_J] 9 |  本ライセンスは、"Minecraft Mod Public License"(以下MMPL) (原文:http://tsoft-web.com/nokiyen/minecraft/modding/MMPL)の日本語訳及びその拡張であり、"Minecraft Mod Public License Japanese Transration"(以下MMPL_J)と呼称する。 10 | 11 | 二条 [構成と効力] 12 |  MMPL_JはA.序文、B.翻訳からなる。MMPL_Jをライセンスとして使用する場合、特に表示のない限りA及びBの両方がライセンスとして効力を持つ。 13 | 14 | 三条 [Bの効力] 15 |  B.翻訳は、MMPLの翻訳部分であり、MMPLと同等の意味内容を持つ。B.翻訳のいかなる翻訳間違えも無効となり、MMPLの該当部分が代わりに適用される。 16 | 17 | 四条 [版] 18 |  B.翻訳はMMPL Version1.0.1の翻訳である。 19 | 20 | 21 | (B.翻訳) 22 | 23 | 0. 定義 24 | -------- 25 | 26 | Minecraft: Mojang ABがライセンスを持つMinecraftというゲームの複製を指す。 27 | 28 | 利用者: 以下のいずれかの方法で当該ソフトウェアに関わるすべての者。 29 | - プレイする 30 | - デコンパイルする 31 | - リコンパイルまたコンパイルする 32 | - 改変する 33 | - 配布する 34 | 35 | Mod: ゲーム拡張のためのコードであり、本ライセンスでは、ソース形式またはバイナリ形式の、それ単体で入手されるもの、より大きな配布の一部分、またはオリジナルのソースもしくは改変されたソースをコンパイルしたものを示す。 36 | 37 | 依存: 当該modが正しく機能するために必要とされるコード。これは、当該コードをコンパイルするのに必要な依存、及び当該modが機能するために明示的または暗黙に必要とされるすべてのファイルまたは改変を含む。 38 | 39 | 40 | 1. 範囲 41 | -------- 42 | 43 | 本ライセンスは当該modのすべての利用者に適用される。前提条件として、利用者は法的に正しく取得されたMinecraftの複製を所持していなければならない。 44 | 45 | 46 | 2. 責任 47 | -------- 48 | 49 | 当該modは、暗黙にせよそうでないにせよ、"現状のもの"が保証なしに提供される。当該modの権利所有者は当該modの利用により受けたいかなる損害に対しても責任を持たない。当該modはMinecraftというゲームの根本的な部分を変えるものであり、Minecraftの一部分が当該modが導入されたことにより機能しない場合がある。当該modの利用や誤用により引き起こされるすべての損害は、利用者が負うこととなる。 50 | 51 | 52 | 3. プレイする権利 53 | -------- 54 | 55 | 利用者は、制限なしに、当該modをクライアントまたはサーバに導入し、プレイすることができる。 56 | 57 | 58 | 4. 改変する権利 59 | -------- 60 | 61 | 利用者は、当該modのソースコードをデコンパイルする、デコンパイルされたまたはオリジナルのソースコードを見る、及びそれを改変する権利を持つ。 62 | 63 | 64 | 5. 引用する権利 65 | -------- 66 | 67 | 利用者は、当該modのコードを引用する、すなわち、当該modのクラスまたはインターフェースを継承またはインスタンス化する、当該modのオブジェクトを参照する、及び当該modの関数をコールする権利を持つ。こうしたコードは"引用"コードとして知られ、当該modと異なるライセンスの元で保障されうる。 68 | 69 | 70 | 6. オリジナルないし改変された著作権物の配布 71 | -------- 72 | 73 | 当該mod全体が、様々な形式において、配布に関する権利に従う。様々な形式とは以下を含む。 74 | - オリジナルの、バイナリまたはソース形式の当該modファイル 75 | - これらのバイナリまたはソースファイルを改変したもの、及びソースを改変することにより得られたバイナリ 76 | - 当該modのソースまたはバイナリファイルへのパッチ 77 | - 当該modのバイナリまたはソースファイルの一部の複製 78 | 79 | 利用者は、当該modの一部分または全体を再配布する、もしくは配布物に含めて再配布することができる。 80 | 81 | バイナリファイルを配布する場合は、利用者は当該modのソースまたは改変したソース全体を入手する手段を無償で提供しなければならない。 82 | 83 | 当該modの配布物のライセンスは、すべてMMPLのままでなければならない。 84 | 85 | 当該modが他のModやクラスに持つ依存はすべて、現行版のMMPLに相当する条件のもとでライセンスが適用されなければならない。ただし、MinecraftのコードとModを読みこむフレームワーク(ModLoader、ModLoaderMP, Bukkitなど)についてはこの限りでない。 86 | 87 | バイナリ及びソースを改変したもの、並びに当該modを複製して得られた部分を含むファイルは、本ライセンスの条項の元で配布されなければならない。 -------------------------------------------------------------------------------- /src/main/java/jp/axer/cocoainput/wrapper/SignEditScreenWrapper.java: -------------------------------------------------------------------------------- 1 | package jp.axer.cocoainput.wrapper; 2 | 3 | import jp.axer.cocoainput.CocoaInput; 4 | import jp.axer.cocoainput.plugin.IMEOperator; 5 | import jp.axer.cocoainput.plugin.IMEReceiver; 6 | import jp.axer.cocoainput.util.ModLogger; 7 | import jp.axer.cocoainput.util.Rect; 8 | import jp.axer.cocoainput.util.WrapperUtil; 9 | import net.minecraft.world.level.block.StandingSignBlock; 10 | import net.minecraft.client.gui.Font; 11 | import net.minecraft.client.gui.screens.inventory.SignEditScreen; 12 | import net.minecraft.network.chat.TextComponent; 13 | 14 | public class SignEditScreenWrapper extends IMEReceiver { 15 | private SignEditScreen owner; 16 | private IMEOperator myIME; 17 | 18 | 19 | public SignEditScreenWrapper(SignEditScreen field) { 20 | ModLogger.debug("SignEditScreen init: " + field.hashCode()); 21 | owner = field; 22 | myIME = CocoaInput.getController().generateIMEOperator(this); 23 | myIME.setFocused(true); 24 | } 25 | 26 | protected void setText(String text) { 27 | owner.sign.setMessage(owner.line,new TextComponent(text)); 28 | String [] util = owner.messages; 29 | util[owner.line]=text; 30 | } 31 | 32 | protected String getText() { 33 | return owner.sign.getMessage(owner.line,false).getString(); 34 | } 35 | 36 | protected void setCursorInvisible() { 37 | owner.frame=6; 38 | } //TODO 39 | 40 | protected int getCursorPos() { 41 | return owner.signField.getCursorPos(); 42 | } 43 | 44 | protected void setCursorPos(int p) { 45 | owner.signField.setCursorPos(p,true); 46 | } 47 | 48 | protected void setSelectionPos(int p) { 49 | owner.signField.setSelectionRange(p,p); 50 | } 51 | 52 | 53 | @Override 54 | public Rect getRect() { 55 | 56 | Font fontRendererObj = null; 57 | try { 58 | fontRendererObj = WrapperUtil.makeFont(owner); 59 | } catch (Exception e) { 60 | e.printStackTrace(); 61 | } 62 | float y = 91 + (owner.line - 1) * (10); 63 | if (!(owner.sign.getBlockState().getBlock() instanceof StandingSignBlock)) { 64 | y += 30; 65 | } 66 | return new Rect( 67 | owner.width/2+fontRendererObj.width(owner.sign.getMessage(owner.line,false).toString().substring(0, originalCursorPosition))/2, 68 | // owner.width / 2 + fontRendererObj.width(owner.sign.getMessage(owner.line,false).getString()) / 2, 69 | y, 70 | 0, 71 | 0 72 | ); 73 | } 74 | public int renewCursorCounter() { 75 | return owner.frame+(cursorVisible?1:0); 76 | } 77 | 78 | } 79 | -------------------------------------------------------------------------------- /fabric/gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%" == "" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%" == "" set DIRNAME=. 29 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 34 | 35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 37 | 38 | @rem Find java.exe 39 | if defined JAVA_HOME goto findJavaFromJavaHome 40 | 41 | set JAVA_EXE=java.exe 42 | %JAVA_EXE% -version >NUL 2>&1 43 | if "%ERRORLEVEL%" == "0" goto execute 44 | 45 | echo. 46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 47 | echo. 48 | echo Please set the JAVA_HOME variable in your environment to match the 49 | echo location of your Java installation. 50 | 51 | goto fail 52 | 53 | :findJavaFromJavaHome 54 | set JAVA_HOME=%JAVA_HOME:"=% 55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 56 | 57 | if exist "%JAVA_EXE%" goto execute 58 | 59 | echo. 60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 61 | echo. 62 | echo Please set the JAVA_HOME variable in your environment to match the 63 | echo location of your Java installation. 64 | 65 | goto fail 66 | 67 | :execute 68 | @rem Setup the command line 69 | 70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 71 | 72 | 73 | @rem Execute Gradle 74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 75 | 76 | :end 77 | @rem End local scope for the variables with windows NT shell 78 | if "%ERRORLEVEL%"=="0" goto mainEnd 79 | 80 | :fail 81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 82 | rem the _cmd.exe /c_ return code! 83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 84 | exit /b 1 85 | 86 | :mainEnd 87 | if "%OS%"=="Windows_NT" endlocal 88 | 89 | :omega 90 | -------------------------------------------------------------------------------- /forge/gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%" == "" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%" == "" set DIRNAME=. 29 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 34 | 35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 37 | 38 | @rem Find java.exe 39 | if defined JAVA_HOME goto findJavaFromJavaHome 40 | 41 | set JAVA_EXE=java.exe 42 | %JAVA_EXE% -version >NUL 2>&1 43 | if "%ERRORLEVEL%" == "0" goto execute 44 | 45 | echo. 46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 47 | echo. 48 | echo Please set the JAVA_HOME variable in your environment to match the 49 | echo location of your Java installation. 50 | 51 | goto fail 52 | 53 | :findJavaFromJavaHome 54 | set JAVA_HOME=%JAVA_HOME:"=% 55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 56 | 57 | if exist "%JAVA_EXE%" goto execute 58 | 59 | echo. 60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 61 | echo. 62 | echo Please set the JAVA_HOME variable in your environment to match the 63 | echo location of your Java installation. 64 | 65 | goto fail 66 | 67 | :execute 68 | @rem Setup the command line 69 | 70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 71 | 72 | 73 | @rem Execute Gradle 74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 75 | 76 | :end 77 | @rem End local scope for the variables with windows NT shell 78 | if "%ERRORLEVEL%"=="0" goto mainEnd 79 | 80 | :fail 81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 82 | rem the _cmd.exe /c_ return code! 83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 84 | exit /b 1 85 | 86 | :mainEnd 87 | if "%OS%"=="Windows_NT" endlocal 88 | 89 | :omega 90 | -------------------------------------------------------------------------------- /src/main/java/jp/axer/cocoainput/arch/darwin/DarwinIMEOperator.java: -------------------------------------------------------------------------------- 1 | package jp.axer.cocoainput.arch.darwin; 2 | 3 | import com.sun.jna.Memory; 4 | import com.sun.jna.Pointer; 5 | import jp.axer.cocoainput.CocoaInput; 6 | import jp.axer.cocoainput.arch.darwin.CallbackFunction.Func_firstRectForCharacterRange; 7 | import jp.axer.cocoainput.arch.darwin.CallbackFunction.Func_insertText; 8 | import jp.axer.cocoainput.arch.darwin.CallbackFunction.Func_setMarkedText; 9 | import jp.axer.cocoainput.plugin.IMEOperator; 10 | import jp.axer.cocoainput.plugin.IMEReceiver; 11 | import jp.axer.cocoainput.util.ModLogger; 12 | import jp.axer.cocoainput.util.Rect; 13 | 14 | import java.util.UUID; 15 | 16 | public class DarwinIMEOperator implements IMEOperator { 17 | IMEReceiver owner; 18 | String uuid; 19 | Func_insertText insertText_p; 20 | Func_setMarkedText setMarkedText_p; 21 | Func_firstRectForCharacterRange firstRectForCharacterRange_p; 22 | boolean isFocused = false; 23 | 24 | public DarwinIMEOperator(IMEReceiver field) { 25 | this.owner = field; 26 | uuid = UUID.randomUUID().toString(); 27 | insertText_p = new Func_insertText() { 28 | @Override 29 | public void invoke(String str, int position, int length) { 30 | ModLogger.debug("Textfield " + uuid + " received inserted text."); 31 | owner.insertText(str, position, length); 32 | } 33 | }; 34 | setMarkedText_p = new Func_setMarkedText() { 35 | @Override 36 | public void invoke(String str, int position1, int length1, 37 | int position2, int length2) { 38 | ModLogger.debug("MarkedText changed at " + uuid + "."); 39 | owner.setMarkedText(str, position1, length1, position2, length2); 40 | ; 41 | } 42 | 43 | }; 44 | firstRectForCharacterRange_p = new Func_firstRectForCharacterRange() { 45 | 46 | @Override 47 | public Pointer invoke() { 48 | ModLogger.debug("Called to determine where to draw."); 49 | Rect point = owner.getRect(); 50 | float[] buff; 51 | if (point == null) { 52 | buff = new float[]{0, 0, 0, 0}; 53 | } else { 54 | buff = new float[]{point.getX(), point.getY(), point.getWidth(), point.getHeight()}; 55 | } 56 | double factor = CocoaInput.getScreenScaledFactor(); 57 | buff[0] *= factor; 58 | buff[1] *= factor; 59 | buff[2] *= factor; 60 | buff[3] *= factor; 61 | 62 | Pointer ret = new Memory(Float.BYTES * 4); 63 | ret.write(0, buff, 0, 4); 64 | return ret; 65 | } 66 | 67 | }; 68 | ModLogger.log("IMEOperator addInstance: " + uuid); 69 | Handle.INSTANCE.addInstance(uuid, insertText_p, setMarkedText_p, firstRectForCharacterRange_p); 70 | } 71 | 72 | public void discardMarkedText() { 73 | Handle.INSTANCE.discardMarkedText(uuid); 74 | } 75 | 76 | public void removeInstance() { 77 | Handle.INSTANCE.removeInstance(uuid); 78 | } 79 | 80 | public void setFocused(boolean yn) { 81 | if (yn != isFocused) { 82 | ModLogger.log("IMEOperator.setFocused: " + (yn ? "true" : "false")); 83 | Handle.INSTANCE.setIfReceiveEvent(uuid, yn ? 1 : 0); 84 | isFocused = yn; 85 | } 86 | } 87 | } -------------------------------------------------------------------------------- /src/main/java/jp/axer/cocoainput/arch/win/WinController.java: -------------------------------------------------------------------------------- 1 | package jp.axer.cocoainput.arch.win; 2 | import java.io.IOException; 3 | import java.lang.reflect.Field; 4 | 5 | import com.sun.jna.Pointer; 6 | import com.sun.jna.WString; 7 | 8 | import jp.axer.cocoainput.CocoaInput; 9 | import jp.axer.cocoainput.arch.win.Handle.DoneCallback; 10 | import jp.axer.cocoainput.arch.win.Handle.PreeditCallback; 11 | import jp.axer.cocoainput.arch.win.Handle.RectCallback; 12 | import jp.axer.cocoainput.plugin.CocoaInputController; 13 | import jp.axer.cocoainput.plugin.IMEOperator; 14 | import jp.axer.cocoainput.plugin.IMEReceiver; 15 | import jp.axer.cocoainput.util.Rect; 16 | import net.minecraft.client.Minecraft; 17 | import net.minecraft.client.gui.screens.Screen; 18 | 19 | public class WinController implements CocoaInputController { 20 | 21 | static WinIMEOperator focusedOperator = null; 22 | 23 | PreeditCallback pc = new PreeditCallback() { 24 | @Override 25 | public void invoke(WString str, int cursor, int length) { 26 | if(focusedOperator!=null) { 27 | Logger.log("marked "+str.toString()+" "+cursor+" "+length); 28 | focusedOperator.owner.setMarkedText(str.toString(), cursor, length,0,0); 29 | } 30 | } 31 | }; 32 | DoneCallback dc = new DoneCallback() { 33 | @Override 34 | public void invoke(WString str) { 35 | if(focusedOperator!=null) { 36 | Logger.log("done ("+str.toString()+")"); 37 | focusedOperator.owner.insertText(str.toString(), 0, 0); 38 | } 39 | } 40 | }; 41 | 42 | RectCallback rc = new RectCallback() { 43 | @Override 44 | public int invoke(Pointer ret) { 45 | if(focusedOperator!=null) { 46 | Logger.log("Rect callback"); 47 | Rect point = focusedOperator.owner.getRect(); 48 | float[] buff; 49 | if (point == null) { 50 | buff = new float[]{0, 0, 0, 0}; 51 | } else { 52 | buff = new float[]{point.getX(), point.getY(), point.getWidth(), point.getHeight()}; 53 | } 54 | double factor = CocoaInput.getScreenScaledFactor(); 55 | buff[0] *= factor; 56 | buff[1] *= factor; 57 | buff[2] *= factor; 58 | buff[3] *= factor; 59 | 60 | ret.write(0, buff, 0, 4); 61 | return 0; 62 | } 63 | return 1; 64 | } 65 | 66 | }; 67 | 68 | public WinController() { 69 | Logger.log("This is Windows Controller"); 70 | try { 71 | CocoaInput.copyLibrary("libwincocoainput.dll", "win/libwincocoainput.dll"); 72 | } catch (IOException e) { 73 | e.printStackTrace(); 74 | } 75 | Handle.INSTANCE.initialize(org.lwjgl.glfw.GLFWNativeWin32.glfwGetWin32Window(Minecraft.getInstance().getWindow().getWindow()), pc, dc,rc, Logger.clangLog, Logger.clangError, Logger.clangDebug); 76 | 77 | } 78 | 79 | 80 | @Override 81 | public IMEOperator generateIMEOperator(IMEReceiver arg0) { 82 | return new WinIMEOperator(arg0); 83 | } 84 | @Override 85 | public void screenOpenNotify(Screen gui) { 86 | try { 87 | Field wrapper = gui.getClass().getField("wrapper"); 88 | wrapper.setAccessible(true); 89 | if (wrapper.get(gui) instanceof IMEReceiver) 90 | return; 91 | } catch (Exception e) { 92 | /* relax */} 93 | if (WinController.focusedOperator != null) { 94 | //WinIMEOperator old=WinController.focusedOperator; 95 | //WinController.focusedOperator=null; 96 | WinController.focusedOperator.setFocused(false); 97 | } 98 | } 99 | 100 | } 101 | -------------------------------------------------------------------------------- /fabric/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'fabric-loom' version '0.10-SNAPSHOT' 3 | id 'maven-publish' 4 | } 5 | 6 | sourceCompatibility = JavaVersion.VERSION_17 7 | targetCompatibility = JavaVersion.VERSION_17 8 | 9 | archivesBaseName = project.archives_base_name 10 | version = project.mod_version 11 | group = project.maven_group 12 | 13 | loom { 14 | accessWidenerPath = file("../src/fabric/resources/cocoainput.accesswidener") 15 | } 16 | 17 | repositories { 18 | // Add repositories to retrieve artifacts from in here. 19 | // You should only use this when depending on other mods because 20 | // Loom adds the essential maven repositories to download Minecraft and libraries from automatically. 21 | // See https://docs.gradle.org/current/userguide/declaring_repositories.html 22 | // for more information about repositories. 23 | maven { url "https://maven.terraformersmc.com/releases/" } 24 | } 25 | 26 | dependencies { 27 | // To change the versions see the gradle.properties file 28 | minecraft "com.mojang:minecraft:${project.minecraft_version}" 29 | mappings minecraft.officialMojangMappings() 30 | modImplementation "net.fabricmc:fabric-loader:${project.loader_version}" 31 | // Fabric API. This is technically optional, but you probably want it anyway. 32 | modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}" 33 | modImplementation "com.terraformersmc:modmenu:${project.modmenu_version}" 34 | // PSA: Some older mods, compiled on Loom 0.2.1, might have outdated Maven POMs. 35 | // You may need to force-disable transitiveness on them. 36 | } 37 | 38 | processResources { 39 | inputs.property "version", project.version 40 | 41 | filesMatching("fabric.mod.json") { 42 | expand "version": project.version 43 | } 44 | } 45 | 46 | tasks.withType(JavaCompile).configureEach { 47 | // ensure that the encoding is set to UTF-8, no matter what the system default is 48 | // this fixes some edge cases with special characters not displaying correctly 49 | // see http://yodaconditions.net/blog/fix-for-java-file-encoding-problems-with-gradle.html 50 | // If Javadoc is generated, this must be specified in that task too. 51 | it.options.encoding = "UTF-8" 52 | 53 | // Minecraft 1.17 (21w19a) upwards uses Java 16. 54 | it.options.release = 17 55 | } 56 | 57 | java { 58 | toolchain { 59 | languageVersion = JavaLanguageVersion.of(17) 60 | } 61 | // Loom will automatically attach sourcesJar to a RemapSourcesJar task and to the "build" task 62 | // if it is present. 63 | // If you remove this line, sources will not be generated. 64 | sourceSets.main.java.srcDirs+=['../src/main'] 65 | sourceSets.main.java.srcDirs+=['../src/fabric'] 66 | 67 | sourceSets.main.resources.srcDirs+=['../src/main/resources'] 68 | sourceSets.main.resources.srcDirs+=['../src/fabric/resources'] 69 | withSourcesJar() 70 | } 71 | 72 | jar { 73 | from("LICENSE") { 74 | rename { "${it}_${project.archivesBaseName}"} 75 | } 76 | } 77 | 78 | // configure the maven publication 79 | publishing { 80 | publications { 81 | mavenJava(MavenPublication) { 82 | // add all the jars that should be included when publishing to maven 83 | artifact(remapJar) { 84 | builtBy remapJar 85 | } 86 | artifact(sourcesJar) { 87 | builtBy remapSourcesJar 88 | } 89 | } 90 | } 91 | 92 | // See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing. 93 | repositories { 94 | // Add repositories to publish to here. 95 | // Notice: This block does NOT have the same function as the block in the top level. 96 | // The repositories here will be used for publishing your artifact, not for 97 | // retrieving dependencies. 98 | } 99 | } 100 | 101 | -------------------------------------------------------------------------------- /src/main/java/jp/axer/cocoainput/CocoaInput.java: -------------------------------------------------------------------------------- 1 | package jp.axer.cocoainput; 2 | 3 | import java.io.File; 4 | import java.io.FileNotFoundException; 5 | import java.io.FileOutputStream; 6 | import java.io.IOException; 7 | import java.io.InputStream; 8 | import java.util.zip.ZipEntry; 9 | import java.util.zip.ZipFile; 10 | 11 | import org.apache.commons.io.IOUtils; 12 | 13 | import com.sun.jna.Platform; 14 | 15 | import jp.axer.cocoainput.arch.darwin.DarwinController; 16 | import jp.axer.cocoainput.arch.dummy.DummyController; 17 | import jp.axer.cocoainput.arch.win.WinController; 18 | import jp.axer.cocoainput.arch.x11.X11Controller; 19 | import jp.axer.cocoainput.plugin.CocoaInputController; 20 | import jp.axer.cocoainput.util.ConfigPack; 21 | import jp.axer.cocoainput.util.ModLogger; 22 | import net.minecraft.client.Minecraft; 23 | import net.minecraft.client.gui.screens.Screen; 24 | 25 | public class CocoaInput { 26 | private static CocoaInputController controller; 27 | private static String zipsource; 28 | public static ConfigPack config = ConfigPack.defaultConfig; 29 | 30 | public CocoaInput(String loader, String zipfile) { 31 | ModLogger.log("Modloader:" + loader); 32 | CocoaInput.zipsource = zipfile; 33 | try { 34 | if (Platform.isMac()) { 35 | CocoaInput.applyController(new DarwinController()); 36 | } else if (Platform.isWindows()) { 37 | CocoaInput.applyController(new WinController()); 38 | } else if (Platform.isX11()) { 39 | CocoaInput.applyController(new X11Controller()); 40 | } else { 41 | ModLogger.log("CocoaInput cannot find appropriate Controller in running OS."); 42 | CocoaInput.applyController(new DummyController()); 43 | } 44 | ModLogger.log("CocoaInput has been initialized."); 45 | } catch (Exception e) { 46 | e.printStackTrace(); 47 | } 48 | } 49 | 50 | public static double getScreenScaledFactor() { 51 | return Minecraft.getInstance().getWindow().getGuiScale(); 52 | } 53 | 54 | public static void applyController(CocoaInputController controller) throws IOException { 55 | CocoaInput.controller = controller; 56 | ModLogger.log("CocoaInput is now using controller:" + controller.getClass().toString()); 57 | } 58 | 59 | public static CocoaInputController getController() { 60 | return CocoaInput.controller; 61 | } 62 | 63 | public void distributeScreen(Screen sc) { 64 | if (CocoaInput.getController() != null) { 65 | CocoaInput.getController().screenOpenNotify(sc); 66 | } 67 | } 68 | 69 | public static void copyLibrary(String libraryName, String libraryPath) throws IOException { 70 | InputStream libFile; 71 | if (zipsource == null) {//Fabric case 72 | libFile = CocoaInput.class.getResourceAsStream("/" + libraryPath); 73 | } else { 74 | try {//Modファイルを検出し、jar内からライブラリを取り出す 75 | ZipFile jarfile = new ZipFile(CocoaInput.zipsource); 76 | libFile = jarfile.getInputStream(new ZipEntry(libraryPath)); 77 | } catch (FileNotFoundException e) {//存在しない場合はデバッグモードであるのでクラスパスからライブラリを取り出す 78 | ModLogger.log("Couldn't get library path. Is this debug mode?'"); 79 | libFile = ClassLoader.getSystemResourceAsStream(libraryPath); 80 | } 81 | } 82 | File nativeDir = new File(Minecraft.getInstance().gameDirectory.getAbsolutePath().concat("/native")); 83 | File copyLibFile = new File( 84 | Minecraft.getInstance().gameDirectory.getAbsolutePath().concat("/native/" + libraryName)); 85 | try { 86 | nativeDir.mkdir(); 87 | FileOutputStream fos = new FileOutputStream(copyLibFile); 88 | copyLibFile.createNewFile(); 89 | IOUtils.copy(libFile, fos); 90 | fos.close(); 91 | } catch (IOException e1) { 92 | ModLogger.error("Attempted to copy library to ./native/" + libraryName + " but failed."); 93 | throw e1; 94 | } 95 | System.setProperty("jna.library.path", nativeDir.getAbsolutePath()); 96 | ModLogger.log("CocoaInput has copied library to native directory."); 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /src/main/java/jp/axer/cocoainput/wrapper/BookEditScreenWrapper.java: -------------------------------------------------------------------------------- 1 | package jp.axer.cocoainput.wrapper; 2 | 3 | import java.util.List; 4 | import java.util.Optional; 5 | 6 | import jp.axer.cocoainput.CocoaInput; 7 | import jp.axer.cocoainput.plugin.IMEOperator; 8 | import jp.axer.cocoainput.plugin.IMEReceiver; 9 | import jp.axer.cocoainput.util.ModLogger; 10 | import jp.axer.cocoainput.util.Rect; 11 | import jp.axer.cocoainput.util.WrapperUtil; 12 | import net.minecraft.client.gui.Font; 13 | import net.minecraft.client.gui.screens.inventory.BookEditScreen; 14 | import net.minecraft.client.StringSplitter; 15 | import net.minecraft.network.chat.FormattedText; 16 | import net.minecraft.network.chat.Style; 17 | 18 | public class BookEditScreenWrapper extends IMEReceiver { 19 | private IMEOperator myIME; 20 | private BookEditScreen owner; 21 | 22 | public BookEditScreenWrapper(BookEditScreen field) { 23 | ModLogger.log("BookEditScreen init: " + field.hashCode()); 24 | owner = field; 25 | myIME = CocoaInput.getController().generateIMEOperator(this); 26 | myIME.setFocused(true); 27 | } 28 | 29 | protected void setText(String text) { 30 | if(owner.isSigning) { 31 | owner.title=text; 32 | } 33 | else { 34 | owner.setCurrentPageText(text); 35 | } 36 | } 37 | 38 | protected String getText() { 39 | if(owner.isSigning) { 40 | return owner.title; 41 | } 42 | else { 43 | return owner.getCurrentPageText(); 44 | } 45 | } 46 | 47 | protected void setCursorInvisible() { 48 | owner.frameTick=6; 49 | } //TODO 50 | 51 | protected int getCursorPos() { 52 | if(owner.isSigning) { 53 | return owner.titleEdit.getCursorPos(); 54 | } 55 | else { 56 | return owner.pageEdit.getCursorPos(); 57 | } 58 | } 59 | 60 | protected void setCursorPos(int p) { 61 | if(owner.isSigning) { 62 | owner.titleEdit.setCursorPos(p,true); 63 | } 64 | else { 65 | owner.pageEdit.setCursorPos(p,true); 66 | } 67 | } 68 | 69 | protected void setSelectionPos(int p) { 70 | if(owner.isSigning) { 71 | owner.titleEdit.setSelectionRange(p, p); 72 | } 73 | else { 74 | owner.pageEdit.setSelectionRange(p, p); 75 | } 76 | } 77 | 78 | 79 | @Override 80 | public Rect getRect() { 81 | Font fontRendererObj = null; 82 | try { 83 | fontRendererObj = WrapperUtil.makeFont(owner); 84 | } catch (Exception e) { 85 | e.printStackTrace(); 86 | } 87 | if (owner.isSigning) { 88 | return new Rect( 89 | (fontRendererObj.width(owner.title.substring(0, originalCursorPosition)) / 2 + ((owner.width - 192) / 2) + 36 + (116 - 0) / 2), 90 | (50 + fontRendererObj.lineHeight), 91 | 0, 92 | 0 93 | ); 94 | } else { 95 | StringSplitter manager = fontRendererObj.getSplitter(); 96 | List lines = manager.splitLines(owner.getCurrentPageText(), 116, Style.EMPTY); 97 | final String[] lastLine = new String[1]; 98 | FormattedText.ContentConsumer acceptor = new FormattedText.ContentConsumer() { 99 | @Override 100 | public Optional accept(String p_accept_1_) { 101 | lastLine[0] = p_accept_1_; 102 | return Optional.empty(); 103 | } 104 | }; 105 | lines.get(lines.size() - 1).visit(acceptor); 106 | return new Rect( 107 | (((owner.width - 192) / 2) + 36 + fontRendererObj.width(lastLine[0])), 108 | (34 + lines.size() * fontRendererObj.lineHeight), 109 | 0, 110 | 0 111 | ); 112 | } 113 | } 114 | 115 | public int renewCursorCounter() { 116 | return owner.frameTick+(cursorVisible?1:0); 117 | } 118 | 119 | } 120 | -------------------------------------------------------------------------------- /src/main/java/jp/axer/cocoainput/arch/x11/X11Controller.java: -------------------------------------------------------------------------------- 1 | package jp.axer.cocoainput.arch.x11; 2 | 3 | import java.io.IOException; 4 | import java.lang.reflect.Field; 5 | 6 | import org.lwjgl.glfw.GLFW; 7 | import org.lwjgl.glfw.GLFWNativeX11; 8 | 9 | import com.sun.jna.Memory; 10 | import com.sun.jna.Pointer; 11 | import com.sun.jna.WString; 12 | 13 | import jp.axer.cocoainput.CocoaInput; 14 | import jp.axer.cocoainput.plugin.CocoaInputController; 15 | import jp.axer.cocoainput.plugin.IMEOperator; 16 | import jp.axer.cocoainput.plugin.IMEReceiver; 17 | import net.minecraft.client.Minecraft; 18 | import net.minecraft.client.gui.screens.Screen; 19 | 20 | public class X11Controller implements CocoaInputController { 21 | 22 | static X11IMEOperator focusedOperator = null; 23 | 24 | Handle.DrawCallback c_draw = new Handle.DrawCallback() { 25 | public Pointer invoke(int caret, int chg_first, int chg_length, short length, boolean iswstring, 26 | String rawstring, WString rawwstring, int primary, int secondary, int tertiary) { 27 | Logger.log("Javaside draw begin"); 28 | String string = iswstring ? rawwstring.toString() : rawstring; 29 | 30 | if (X11Controller.focusedOperator != null) { 31 | GLFW.glfwSetKeyCallback(window, null); 32 | X11Controller.focusedOperator.owner.setMarkedText(string, caret, tertiary - secondary, 0, 0); 33 | } 34 | Logger.log("Preedit:" + caret + " " + chg_first + " " + chg_length + " " + length + " " + primary + " " 35 | + secondary + " " + tertiary + " " + string); 36 | int[] point = { 600, 600 }; 37 | Memory memory = new Memory(8L); 38 | memory.write(0L, point, 0, 2); 39 | Logger.log("Javaside draw end"); 40 | return (Pointer) memory; 41 | } 42 | }; 43 | 44 | Handle.DoneCallback c_done = new Handle.DoneCallback() { 45 | public void invoke() { 46 | Logger.log("javaside preedit done"); 47 | if (X11Controller.focusedOperator != null) { 48 | X11Controller.focusedOperator.owner.insertText("", 0, 0); 49 | } 50 | setupKeyboardEvent(); 51 | } 52 | }; 53 | 54 | public static void setupKeyboardEvent() { 55 | Minecraft.getInstance().keyboardHandler.setup(window); 56 | GLFW.glfwSetCharModsCallback(window, (p_228000_1_, p_228000_3_, p_228000_4_) -> { 57 | Minecraft.getInstance().execute(() -> { 58 | if (X11Controller.focusedOperator != null) { 59 | 60 | X11Controller.focusedOperator.owner.insertText(String.valueOf(Character.toChars(p_228000_3_)), 0, 61 | 0); 62 | 63 | } else { 64 | Minecraft.getInstance().keyboardHandler.charTyped(p_228000_1_, p_228000_3_, p_228000_4_); 65 | } 66 | }); 67 | }); 68 | } 69 | 70 | private static final long window = Minecraft.getInstance().getWindow().getWindow(); 71 | 72 | public X11Controller() throws IOException { 73 | 74 | setupKeyboardEvent(); 75 | 76 | Logger.log("This is X11 Controller"); 77 | CocoaInput.copyLibrary("libx11cocoainput.so", "x11/libx11cocoainput.so"); 78 | Logger.log("Call clang initializer"); 79 | Handle.INSTANCE.initialize(window, GLFWNativeX11.glfwGetX11Window(window), this.c_draw, this.c_done, 80 | Logger.clangLog, Logger.clangError, Logger.clangDebug); 81 | Handle.INSTANCE.set_focus(0); 82 | Logger.log("Finished clang initializer"); 83 | Logger.log("X11Controller finished initialize"); 84 | 85 | } 86 | 87 | @Override 88 | public IMEOperator generateIMEOperator(IMEReceiver arg0) { 89 | // TODO Auto-generated method stub 90 | return new X11IMEOperator(arg0); 91 | } 92 | 93 | @Override 94 | public void screenOpenNotify(Screen gui) { 95 | try { 96 | Field wrapper = gui.getClass().getField("wrapper"); 97 | wrapper.setAccessible(true); 98 | if (wrapper.get(gui) instanceof IMEReceiver) 99 | return; 100 | } catch (Exception e) { 101 | /* relax */} 102 | if (X11Controller.focusedOperator != null) { 103 | X11Controller.focusedOperator.setFocused(false); 104 | X11Controller.focusedOperator = null; 105 | } 106 | } 107 | 108 | } 109 | -------------------------------------------------------------------------------- /libcocoainput/darwin/libcocoainput/cocoainput.m: -------------------------------------------------------------------------------- 1 | // 2 | // cocoainput.m 3 | // libcocoainput 4 | // 5 | // Created by Axer on 2019/03/23. 6 | // Copyright © 2019年 Axer. All rights reserved. 7 | // 8 | #import 9 | #import 10 | #import "cocoainput.h" 11 | #import "DataManager.h" 12 | 13 | void replaceInstanceMethod(Class cls, SEL sel, SEL renamedSel, Class dataCls) { 14 | Method methodReplacedWith = class_getInstanceMethod(cls, sel); 15 | IMP imp = method_getImplementation(methodReplacedWith); 16 | const char* encoding = method_getTypeEncoding(methodReplacedWith); 17 | class_addMethod(cls, renamedSel, imp, encoding); 18 | methodReplacedWith = class_getInstanceMethod(dataCls, sel); 19 | imp = method_getImplementation(methodReplacedWith); 20 | encoding = method_getTypeEncoding(methodReplacedWith); 21 | class_replaceMethod(cls, sel, imp, encoding); 22 | } 23 | 24 | void initialize(LogFunction log,LogFunction error,LogFunction debug){ 25 | initLogPointer(log, error, debug); 26 | CILog([NSString stringWithFormat:@"Libcocoainput was built on %s %s.", __DATE__, __TIME__]); 27 | CILog(@"CocoaInput is being initialized.Now running thread for modify GLFWview ."); 28 | NSThread *thread=[[NSThread alloc]initWithTarget:[DataManager sharedManager] selector:@selector(modifyGLFWView) object:nil]; 29 | [thread start]; 30 | } 31 | 32 | void addInstance(const char* uuid, 33 | void (*insertText_p)(const char*, const int, const int), 34 | void (*setMarkedText_p)(const char*, 35 | const int, 36 | const int, 37 | const int, 38 | const int), 39 | float* (*firstRectForCharacterRange_p)(void)) { 40 | CIDebug([NSString stringWithFormat:@"New textfield %s has registered.", uuid]); 41 | MinecraftView* mc = [[MinecraftView alloc] init]; 42 | mc.insertText = insertText_p; 43 | mc.setMarkedText = setMarkedText_p; 44 | mc.firstRectForCharacterRange = firstRectForCharacterRange_p; 45 | [[[DataManager sharedManager] dic] 46 | setObject:mc 47 | forKey:[[NSString alloc] initWithCString:uuid 48 | encoding:NSUTF8StringEncoding]]; 49 | } 50 | 51 | void removeInstance(const char* uuid) { 52 | CIDebug([NSString stringWithFormat:@"Textfield %s has been removed.", uuid]); 53 | [[[DataManager sharedManager] dic] 54 | removeObjectForKey:[[NSString alloc] 55 | initWithCString:uuid 56 | encoding:NSUTF8StringEncoding]]; 57 | } 58 | 59 | void refreshInstance(void) { 60 | CIDebug(@"All textfields has been removed."); 61 | [[NSTextInputContext currentInputContext] discardMarkedText]; 62 | [DataManager sharedManager].activeView = nil; 63 | [DataManager sharedManager].dic = [NSMutableDictionary dictionary]; 64 | } 65 | 66 | void discardMarkedText(const char* uuid) { 67 | CIDebug(@"Active marked text has been discarded."); 68 | } 69 | 70 | void setIfReceiveEvent(const char* uuid, int yn) { 71 | CIDebug([NSString stringWithFormat:@"Textfield %s's flag has changed to %d.", 72 | uuid, yn]); 73 | if (yn == 1) { 74 | [DataManager sharedManager].activeView = [[[DataManager sharedManager] dic] 75 | objectForKey:[[NSString alloc] initWithCString:uuid 76 | encoding:NSUTF8StringEncoding]]; 77 | } else { 78 | if ([DataManager sharedManager].activeView != nil && 79 | [[[[DataManager sharedManager] dic] 80 | objectForKey:[[NSString alloc] 81 | initWithCString:uuid 82 | encoding:NSUTF8StringEncoding]] 83 | isEqual:[DataManager sharedManager].activeView]) 84 | [DataManager sharedManager].activeView = nil; 85 | } 86 | } 87 | 88 | float invertYCoordinate(float y) { 89 | CIDebug(@"InvertYCoordinate function used"); 90 | return [[NSScreen mainScreen] visibleFrame].size.height + 91 | [[NSScreen mainScreen] visibleFrame].origin.y - y; 92 | } 93 | -------------------------------------------------------------------------------- /src/main/java/jp/axer/cocoainput/plugin/IMEReceiver.java: -------------------------------------------------------------------------------- 1 | package jp.axer.cocoainput.plugin; 2 | 3 | import jp.axer.cocoainput.CocoaInput; 4 | import jp.axer.cocoainput.arch.win.Logger; 5 | import jp.axer.cocoainput.util.PreeditFormatter; 6 | import jp.axer.cocoainput.util.Rect; 7 | import jp.axer.cocoainput.util.Tuple3; 8 | import net.minecraft.client.Minecraft; 9 | 10 | public abstract class IMEReceiver { 11 | 12 | private int length = 0; 13 | protected boolean cursorVisible = true; 14 | private boolean preeditBegin = false; 15 | protected int originalCursorPosition = 0; 16 | 17 | /* 18 | * position1 length1は下線と強調変換のため必須 position2 length2は意味をなしてない 19 | * positionの位置から文字数lengthの範囲という意味 20 | */ 21 | public void insertText(String aString, int position1, int length1) {//確定文字列 現状aString以外の引数は意味をなしてない 22 | if (true) { 23 | Logger.log("just comming:(" + aString + ") now:(" + getText() + ")"); 24 | } 25 | if (!preeditBegin) { 26 | originalCursorPosition = this.getCursorPos(); 27 | } 28 | preeditBegin = false; 29 | cursorVisible = true; 30 | this.setText((new StringBuffer(this.getText())) 31 | .replace(originalCursorPosition, originalCursorPosition + length, "").toString()); 32 | length = 0; 33 | this.setCursorPos(originalCursorPosition); 34 | this.setSelectionPos(originalCursorPosition); 35 | if (CocoaInput.config.isNativeCharTyped()) { 36 | this.insertTextNative(aString); 37 | } else { 38 | this.insertTextEmurated(aString); 39 | } 40 | /* 41 | if (aString.length() == 0) { 42 | this.setText((new StringBuffer(this.getText())) 43 | .replace(originalCursorPosition, originalCursorPosition + length, "").toString()); 44 | length = 0; 45 | this.setCursorPos(originalCursorPosition); 46 | this.setSelectionPos(originalCursorPosition); 47 | return; 48 | } 49 | this.setText((new StringBuffer(this.getText())) 50 | .replace(originalCursorPosition, originalCursorPosition + length, 51 | aString.substring(0, aString.length())) 52 | .toString()); 53 | length = 0; 54 | this.setCursorPos(originalCursorPosition + aString.length()); 55 | this.notifyParent(this.getText()); 56 | //owner.selectionEnd = owner.cursorPosition; 57 | */ 58 | } 59 | 60 | public void setMarkedText(String aString, int position1, int length1, int position2, int length2) { 61 | if (!preeditBegin) { 62 | originalCursorPosition = this.getCursorPos(); 63 | preeditBegin = true; 64 | } 65 | int caretPosition; 66 | boolean hasCaret; 67 | String commitString; 68 | if (CocoaInput.config.isAdvancedPreeditDraw()) { 69 | Tuple3 formattedText = PreeditFormatter.formatMarkedText(aString, position1, 70 | length1); 71 | commitString = formattedText._1(); 72 | caretPosition = formattedText._2() + 4;//相対値 73 | hasCaret = formattedText._3(); 74 | 75 | } 76 | else { 77 | hasCaret=true; 78 | caretPosition=0; 79 | commitString=PreeditFormatter.SECTION+"n"+aString+PreeditFormatter.SECTION+"r"; 80 | } 81 | this.setText((new StringBuffer(this.getText())) 82 | .replace(originalCursorPosition, originalCursorPosition + length, commitString).toString()); 83 | length = commitString.length(); 84 | if (hasCaret) { 85 | this.cursorVisible = true; 86 | this.setCursorPos(originalCursorPosition + caretPosition); 87 | this.setSelectionPos(originalCursorPosition + caretPosition); 88 | } else { 89 | this.cursorVisible = false; 90 | this.setCursorInvisible(); 91 | this.setCursorPos(originalCursorPosition); 92 | this.setSelectionPos(originalCursorPosition); 93 | //owner.selectionEnd=owner.cursorPosition; 94 | } 95 | } 96 | 97 | public abstract Rect getRect(); 98 | 99 | abstract protected void setText(String text); 100 | 101 | abstract protected String getText(); 102 | 103 | abstract protected void setCursorInvisible(); 104 | 105 | abstract protected int getCursorPos(); 106 | 107 | abstract protected void setCursorPos(int p); 108 | 109 | abstract protected void setSelectionPos(int p); 110 | 111 | protected void insertTextNative(String text) { 112 | for (char c : text.toCharArray()) { 113 | Minecraft instance = Minecraft.getInstance(); 114 | instance.keyboardHandler.charTyped(instance.getWindow().getWindow(), c, 0); 115 | } 116 | } 117 | 118 | protected void insertTextEmurated(String aString) { 119 | this.setText((new StringBuffer(this.getText())) 120 | .replace(this.getCursorPos(), this.getCursorPos(), 121 | aString.substring(0, aString.length())) 122 | .toString()); 123 | length = 0; 124 | this.setCursorPos(this.getCursorPos() + aString.length()); 125 | this.notifyParent(this.getText()); 126 | } 127 | 128 | protected void notifyParent(String text) { 129 | }; 130 | } 131 | -------------------------------------------------------------------------------- /libcocoainput/win/libwincocoainput.c: -------------------------------------------------------------------------------- 1 | #include "libwincocoainput.h" 2 | #include 3 | 4 | void (*javaDone)(wchar_t*); 5 | int* (*javaDraw)(wchar_t*,int,int); 6 | int (*javaRect)(float*); 7 | 8 | 9 | 10 | void setCallback(int*(*c_draw)(wchar_t*,int,int),void(*c_done)(wchar_t*),int (*c_rect)(float*)){ 11 | javaDraw=c_draw; 12 | javaDone=c_done; 13 | javaRect=c_rect; 14 | } 15 | 16 | 17 | HWND hwnd; 18 | HIMC himc; 19 | 20 | 21 | LRESULT compositionLocationNotify(HWND hWnd){ 22 | HIMC imc=NULL; 23 | float *rect= malloc(sizeof(float)*4); 24 | CILog("ready call javaRect"); 25 | if(javaRect(rect)){ 26 | free(rect); 27 | return FALSE; 28 | } 29 | CANDIDATEFORM rectStruct = {0,CFS_EXCLUDE,{rect[0],rect[1]},{rect[0]-rect[2],rect[1]-rect[3],rect[0]+1,rect[1]+1}}; 30 | imc=ImmGetContext(hwnd); 31 | ImmSetCandidateWindow(imc,&rectStruct); 32 | ImmReleaseContext(hWnd,imc); 33 | free(rect); 34 | return TRUE; 35 | } 36 | 37 | LRESULT CALLBACK (*glfwWndProc)(HWND,UINT,WPARAM,LPARAM); 38 | LRESULT CALLBACK wrapper_wndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam){ 39 | switch(msg){ 40 | case WM_IME_NOTIFY:{ 41 | if(wParam==IMN_OPENCANDIDATE){ 42 | compositionLocationNotify(hWnd); 43 | return TRUE; 44 | } 45 | else{ 46 | break; 47 | } 48 | } 49 | case WM_IME_STARTCOMPOSITION:{ 50 | compositionLocationNotify(hWnd); 51 | return TRUE; 52 | } 53 | case WM_IME_ENDCOMPOSITION:{ 54 | javaDone(L""); 55 | return TRUE; 56 | } 57 | case WM_IME_COMPOSITION:{ 58 | HIMC imc=NULL; 59 | LONG textSize,attrSize,clauseSize; 60 | int i, focusedBlock, length; 61 | LPWSTR buffer; 62 | LPSTR attributes; 63 | DWORD* clauses; 64 | LONG cursor=0; 65 | if(lParam&GCS_RESULTSTR){ 66 | CILog("ResultStr"); 67 | imc=ImmGetContext(hwnd); 68 | textSize = ImmGetCompositionStringW(imc, GCS_RESULTSTR, NULL, 0); 69 | length = textSize / sizeof(WCHAR); 70 | buffer = calloc(length + 1, sizeof(WCHAR)); 71 | ImmGetCompositionStringW(imc, GCS_RESULTSTR, buffer, textSize); 72 | ImmReleaseContext(hWnd, imc); 73 | javaDone(buffer); 74 | } 75 | if(lParam&GCS_COMPSTR){ 76 | imc=ImmGetContext(hwnd); 77 | if(lParam&GCS_CURSORPOS){ 78 | cursor=ImmGetCompositionStringW(imc, GCS_CURSORPOS, NULL, 0); 79 | } 80 | 81 | textSize = ImmGetCompositionStringW(imc, GCS_COMPSTR, NULL, 0); 82 | attrSize = ImmGetCompositionStringW(imc, GCS_COMPATTR, NULL, 0); 83 | clauseSize = ImmGetCompositionStringW(imc, GCS_COMPCLAUSE, NULL, 0); 84 | if(textSize<=0){ 85 | ImmReleaseContext(hWnd, imc); 86 | javaDone(L""); 87 | } 88 | else{ 89 | length = textSize / sizeof(WCHAR); 90 | buffer = calloc(length + 1, sizeof(WCHAR)); 91 | attributes = calloc(attrSize, 1); 92 | clauses = calloc(clauseSize, 1); 93 | ImmGetCompositionStringW(imc, GCS_COMPSTR, buffer, textSize); 94 | ImmGetCompositionStringW(imc, GCS_COMPATTR, attributes, attrSize); 95 | ImmGetCompositionStringW(imc, GCS_COMPCLAUSE, clauses, clauseSize); 96 | ImmReleaseContext(hWnd, imc); 97 | int selected_begin=-1; 98 | int selected_length=0; 99 | int i; 100 | for(i=0;i=0){ 109 | cursor=selected_begin; 110 | } 111 | compositionLocationNotify(hWnd); 112 | javaDraw(buffer,cursor,selected_length); 113 | } 114 | } 115 | return TRUE; 116 | } 117 | default:break; 118 | } 119 | return CallWindowProc(glfwWndProc,hWnd,msg,wParam,lParam); 120 | } 121 | 122 | 123 | 124 | void initialize( 125 | long hwndp, 126 | int*(*c_draw)(wchar_t*,int,int), 127 | void(*c_done)(wchar_t*), 128 | int (*c_rect)(float*), 129 | LogFunction log, 130 | LogFunction error, 131 | LogFunction debug 132 | ){ 133 | initLogPointer(log,error,debug); 134 | CILog("CocoaInput Windows Clang Initializer start. library compiled at %s %s",__DATE__,__TIME__); 135 | setCallback(c_draw,c_done,c_rect); 136 | hwnd=(HWND)hwndp; 137 | glfwWndProc = GetWindowLongPtr(hwnd,GWLP_WNDPROC); 138 | SetWindowLongPtr(hwnd,GWLP_WNDPROC,wrapper_wndProc); 139 | CILog("Window procedure replaced"); 140 | //input_himc = ImmGetContext(hwnd); 141 | /*if(!hImc){ 142 | hImc = ImmCreateContext(); 143 | HIMC oldhImc = ImmAssociateContext( hwnd, hImc ); 144 | }*/ 145 | //ImmReleaseContext(hwnd,input_himc); 146 | himc = ImmGetContext(hwnd); 147 | if(!himc){ 148 | himc = ImmCreateContext(); 149 | } 150 | ImmReleaseContext(hwnd,himc); 151 | himc=ImmAssociateContext(hwnd,0); 152 | CILog("CocoaInput Windows initializer done!"); 153 | } 154 | 155 | void set_focus(int flag){ 156 | 157 | CILog("setFocused:%d",flag); 158 | if(flag){ 159 | ImmAssociateContext(hwnd,himc); 160 | compositionLocationNotify(hwnd); 161 | } 162 | else{ 163 | himc=ImmAssociateContext(hwnd,0); 164 | } 165 | } 166 | -------------------------------------------------------------------------------- /libcocoainput/x11/libx11cocoainput.c: -------------------------------------------------------------------------------- 1 | #include "libx11cocoainput.h" 2 | 3 | void (*javaDone)(); 4 | int* (*javaDraw)(int,int,int,short,int,char*,wchar_t*,int,int,int); 5 | XICCallback calet,start,done,draw; 6 | XICCallback s_start,s_done,s_draw; 7 | 8 | 9 | 10 | 11 | void setCallback(int*(*c_draw)(int,int,int,short,int,char*,wchar_t*,int,int,int),void(*c_done)()){ 12 | javaDraw=c_draw; 13 | javaDone=c_done; 14 | } 15 | 16 | 17 | int preeditCalet(XIC xic,XPointer clientData,XPointer data){ 18 | return 0; 19 | } 20 | int preeditStart(XIC xic,XPointer clientData,XPointer data){ 21 | CILog("Preedit start"); 22 | return 0; 23 | } 24 | int preeditDone(XIC xic,XPointer clientData,XPointer data){ 25 | CILog("Preedit end"); 26 | javaDone(); 27 | return 0; 28 | } 29 | int preeditDraw(XIC xic,XPointer clientData,XPointer structptr){ 30 | CILog("Preedit draw start"); 31 | XIMPreeditDrawCallbackStruct* structure=(XIMPreeditDrawCallbackStruct*)structptr; 32 | int *array; 33 | int secondary=0; 34 | int length=0; 35 | if(structure->text){ 36 | int i=0; 37 | int secondary_determined=0; 38 | for(i=0;i!=structure->text->length;i++){ 39 | if(!secondary_determined&&structure->text->feedback[i]!=XIMUnderline){ 40 | secondary=i; 41 | secondary_determined=1; 42 | } 43 | if(secondary_determined&&(structure->text->feedback[i]==0||structure->text->feedback[i]!=XIMUnderline)){ 44 | length++; 45 | } 46 | else if(secondary_determined)break; 47 | } 48 | } 49 | 50 | CILog("Invoke Javaside"); 51 | if(structure->text){ 52 | array=javaDraw( 53 | structure->caret, 54 | structure->chg_first, 55 | structure->chg_length, 56 | structure->text->length, 57 | structure->text->encoding_is_wchar, 58 | structure->text->encoding_is_wchar?"":structure->text->string.multi_byte, 59 | structure->text->encoding_is_wchar?structure->text->string.wide_char:L"", 60 | 0, 61 | secondary, 62 | secondary+length 63 | ); 64 | } 65 | else { 66 | array=javaDraw( 67 | structure->caret, 68 | structure->chg_first, 69 | structure->chg_length, 70 | 0, 71 | 0, 72 | "", 73 | L"", 74 | 0, 75 | 0, 76 | 0 77 | ); 78 | } 79 | 80 | //TODO なんとかしてon-the-spotの候補ウィンドウをちゃんとした位置にしたいね(願望) 81 | XVaNestedList attr; 82 | XPoint place; 83 | place.x=array[0];place.y=array[1]; 84 | attr=XVaCreateNestedList(0,XNSpotLocation,&place,NULL); 85 | XSetICValues(xic,XNPreeditAttributes,attr,NULL); 86 | XFree(attr); 87 | CILog("Preedit draw end"); 88 | return 0; 89 | } 90 | 91 | int statusStart(XIC xic,XPointer clientData,XPointer data){ 92 | return 0; 93 | } 94 | int statusDone(XIC xic,XPointer clientData,XPointer data){ 95 | return 0; 96 | } 97 | int statusDraw(XIC xic,XPointer clientData,XPointer data/*,XIMStatusDrawCallbackStruct *structure*/){ 98 | return 0; 99 | } 100 | 101 | 102 | 103 | XVaNestedList preeditCallbacksList(){ 104 | calet.client_data=NULL; 105 | start.client_data=NULL; 106 | done.client_data=NULL; 107 | draw.client_data=NULL; 108 | calet.callback=preeditCalet; 109 | start.callback=preeditStart; 110 | done.callback=preeditDone; 111 | draw.callback=preeditDraw; 112 | return XVaCreateNestedList(0, 113 | XNPreeditStartCallback, 114 | &start, 115 | XNPreeditCaretCallback, 116 | &calet, 117 | XNPreeditDoneCallback, 118 | &done, 119 | XNPreeditDrawCallback, 120 | &draw,NULL); 121 | } 122 | 123 | 124 | XVaNestedList statusCallbacksList(){ 125 | s_start.client_data=NULL; 126 | s_done.client_data=NULL; 127 | s_draw.client_data=NULL; 128 | s_start.callback=statusStart; 129 | s_done.callback=statusDone; 130 | s_draw.callback=statusDraw; 131 | return XVaCreateNestedList(0, 132 | XNStatusStartCallback, 133 | &s_start, 134 | XNStatusDoneCallback, 135 | &s_done, 136 | XNStatusDrawCallback, 137 | &s_draw,NULL); 138 | } 139 | 140 | 141 | 142 | _GLFWwindowX11 * x11c; //_GLFWwindowX11のアドレス 143 | XIM xim; //_GLFWwindowX11が保持するXIM 144 | Window xwindow; // 145 | 146 | 147 | XIC activeic; // IMが有効なIC 148 | XIC inactiveic; //IMが無効なIC 149 | 150 | 151 | 152 | void initialize( 153 | long waddr, 154 | long xw, 155 | int*(*c_draw)(int,int,int,short,int,char*,wchar_t*,int,int,int), 156 | void(*c_done)(), 157 | LogFunction log, 158 | LogFunction error, 159 | LogFunction debug 160 | ){ 161 | initLogPointer(log,error,debug); 162 | CILog("CocoaInput X11 Clang Initializer start. library compiled at %s %s",__DATE__,__TIME__); 163 | 164 | setCallback(c_draw,c_done); 165 | 166 | CILog("Window ptr:%p",(Window)xw); 167 | CILog("GLFWwindow ptr:%p",(void*)waddr); 168 | CILog("Searching _GLFWwindowx11 from GLFWwindow ptr..."); 169 | int i; 170 | XIC ic=NULL; 171 | for(i=0;i<0x500;i++){ 172 | Window po = (*(((_GLFWwindowX11*)(waddr+i)))).handle; 173 | if(po!=xw)continue; 174 | x11c = (((_GLFWwindowX11*)(waddr+i))); 175 | ic = (*(((_GLFWwindowX11*)(waddr+i)))).ic; 176 | CILog("Found offset:%d ,_GLFWwindowX11(%p)=GLFWwindow(%p)+%d ",i,x11c,(void*)waddr,i); 177 | break; 178 | } 179 | CILog("XIC mem address:%p",x11c->ic); 180 | xim = XIMOfIC(ic); 181 | CILog("XIM mem address:%p",xim); 182 | xwindow=xw; 183 | inactiveic = XCreateIC( 184 | xim, 185 | XNClientWindow, 186 | (Window)xwindow, 187 | XNFocusWindow, 188 | (Window)xwindow, 189 | XNInputStyle, 190 | XIMPreeditNone|XIMStatusNone, 191 | NULL); 192 | CILog("Created inactiveic-> default"); 193 | activeic = XCreateIC( 194 | xim, 195 | XNClientWindow, 196 | xwindow, 197 | XNFocusWindow, 198 | xwindow, 199 | XNInputStyle, 200 | XIMPreeditCallbacks|XIMStatusNone, 201 | //XIMPreeditNothing|XIMStatusNothing, 202 | XNPreeditAttributes, 203 | preeditCallbacksList(), 204 | XNStatusAttributes, 205 | statusCallbacksList(), 206 | NULL); 207 | CILog("Created activeic"); 208 | XSetICFocus(inactiveic); 209 | XUnsetICFocus(activeic); 210 | CILog("Completed ic focus"); 211 | XDestroyIC(x11c->ic); 212 | x11c->ic = inactiveic; 213 | CILog("Destroyed glfw ic"); 214 | CILog("CocoaInput X11 initializer done!"); 215 | } 216 | 217 | void set_focus(int flag){ 218 | XUnsetICFocus(x11c->ic); 219 | if(flag){ 220 | x11c->ic=activeic; 221 | } 222 | else{ 223 | x11c->ic= inactiveic; 224 | } 225 | XSetICFocus(x11c->ic); 226 | CILog("setFocused:%d",flag); 227 | } 228 | -------------------------------------------------------------------------------- /fabric/gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | # 4 | # Copyright 2015 the original author or authors. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # https://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | 19 | ############################################################################## 20 | ## 21 | ## Gradle start up script for UN*X 22 | ## 23 | ############################################################################## 24 | 25 | # Attempt to set APP_HOME 26 | # Resolve links: $0 may be a link 27 | PRG="$0" 28 | # Need this for relative symlinks. 29 | while [ -h "$PRG" ] ; do 30 | ls=`ls -ld "$PRG"` 31 | link=`expr "$ls" : '.*-> \(.*\)$'` 32 | if expr "$link" : '/.*' > /dev/null; then 33 | PRG="$link" 34 | else 35 | PRG=`dirname "$PRG"`"/$link" 36 | fi 37 | done 38 | SAVED="`pwd`" 39 | cd "`dirname \"$PRG\"`/" >/dev/null 40 | APP_HOME="`pwd -P`" 41 | cd "$SAVED" >/dev/null 42 | 43 | APP_NAME="Gradle" 44 | APP_BASE_NAME=`basename "$0"` 45 | 46 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 47 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' 48 | 49 | # Use the maximum available, or set MAX_FD != -1 to use that value. 50 | MAX_FD="maximum" 51 | 52 | warn () { 53 | echo "$*" 54 | } 55 | 56 | die () { 57 | echo 58 | echo "$*" 59 | echo 60 | exit 1 61 | } 62 | 63 | # OS specific support (must be 'true' or 'false'). 64 | cygwin=false 65 | msys=false 66 | darwin=false 67 | nonstop=false 68 | case "`uname`" in 69 | CYGWIN* ) 70 | cygwin=true 71 | ;; 72 | Darwin* ) 73 | darwin=true 74 | ;; 75 | MINGW* ) 76 | msys=true 77 | ;; 78 | NONSTOP* ) 79 | nonstop=true 80 | ;; 81 | esac 82 | 83 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 84 | 85 | 86 | # Determine the Java command to use to start the JVM. 87 | if [ -n "$JAVA_HOME" ] ; then 88 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 89 | # IBM's JDK on AIX uses strange locations for the executables 90 | JAVACMD="$JAVA_HOME/jre/sh/java" 91 | else 92 | JAVACMD="$JAVA_HOME/bin/java" 93 | fi 94 | if [ ! -x "$JAVACMD" ] ; then 95 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 96 | 97 | Please set the JAVA_HOME variable in your environment to match the 98 | location of your Java installation." 99 | fi 100 | else 101 | JAVACMD="java" 102 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 103 | 104 | Please set the JAVA_HOME variable in your environment to match the 105 | location of your Java installation." 106 | fi 107 | 108 | # Increase the maximum file descriptors if we can. 109 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 110 | MAX_FD_LIMIT=`ulimit -H -n` 111 | if [ $? -eq 0 ] ; then 112 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 113 | MAX_FD="$MAX_FD_LIMIT" 114 | fi 115 | ulimit -n $MAX_FD 116 | if [ $? -ne 0 ] ; then 117 | warn "Could not set maximum file descriptor limit: $MAX_FD" 118 | fi 119 | else 120 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 121 | fi 122 | fi 123 | 124 | # For Darwin, add options to specify how the application appears in the dock 125 | if $darwin; then 126 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 127 | fi 128 | 129 | # For Cygwin or MSYS, switch paths to Windows format before running java 130 | if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then 131 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 132 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 133 | 134 | JAVACMD=`cygpath --unix "$JAVACMD"` 135 | 136 | # We build the pattern for arguments to be converted via cygpath 137 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 138 | SEP="" 139 | for dir in $ROOTDIRSRAW ; do 140 | ROOTDIRS="$ROOTDIRS$SEP$dir" 141 | SEP="|" 142 | done 143 | OURCYGPATTERN="(^($ROOTDIRS))" 144 | # Add a user-defined pattern to the cygpath arguments 145 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 146 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 147 | fi 148 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 149 | i=0 150 | for arg in "$@" ; do 151 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 152 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 153 | 154 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 155 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 156 | else 157 | eval `echo args$i`="\"$arg\"" 158 | fi 159 | i=`expr $i + 1` 160 | done 161 | case $i in 162 | 0) set -- ;; 163 | 1) set -- "$args0" ;; 164 | 2) set -- "$args0" "$args1" ;; 165 | 3) set -- "$args0" "$args1" "$args2" ;; 166 | 4) set -- "$args0" "$args1" "$args2" "$args3" ;; 167 | 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 168 | 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 169 | 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 170 | 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 171 | 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 172 | esac 173 | fi 174 | 175 | # Escape application args 176 | save () { 177 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done 178 | echo " " 179 | } 180 | APP_ARGS=`save "$@"` 181 | 182 | # Collect all arguments for the java command, following the shell quoting and substitution rules 183 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" 184 | 185 | exec "$JAVACMD" "$@" 186 | -------------------------------------------------------------------------------- /forge/gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | # 4 | # Copyright 2015 the original author or authors. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # https://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | 19 | ############################################################################## 20 | ## 21 | ## Gradle start up script for UN*X 22 | ## 23 | ############################################################################## 24 | 25 | # Attempt to set APP_HOME 26 | # Resolve links: $0 may be a link 27 | PRG="$0" 28 | # Need this for relative symlinks. 29 | while [ -h "$PRG" ] ; do 30 | ls=`ls -ld "$PRG"` 31 | link=`expr "$ls" : '.*-> \(.*\)$'` 32 | if expr "$link" : '/.*' > /dev/null; then 33 | PRG="$link" 34 | else 35 | PRG=`dirname "$PRG"`"/$link" 36 | fi 37 | done 38 | SAVED="`pwd`" 39 | cd "`dirname \"$PRG\"`/" >/dev/null 40 | APP_HOME="`pwd -P`" 41 | cd "$SAVED" >/dev/null 42 | 43 | APP_NAME="Gradle" 44 | APP_BASE_NAME=`basename "$0"` 45 | 46 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 47 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' 48 | 49 | # Use the maximum available, or set MAX_FD != -1 to use that value. 50 | MAX_FD="maximum" 51 | 52 | warn () { 53 | echo "$*" 54 | } 55 | 56 | die () { 57 | echo 58 | echo "$*" 59 | echo 60 | exit 1 61 | } 62 | 63 | # OS specific support (must be 'true' or 'false'). 64 | cygwin=false 65 | msys=false 66 | darwin=false 67 | nonstop=false 68 | case "`uname`" in 69 | CYGWIN* ) 70 | cygwin=true 71 | ;; 72 | Darwin* ) 73 | darwin=true 74 | ;; 75 | MINGW* ) 76 | msys=true 77 | ;; 78 | NONSTOP* ) 79 | nonstop=true 80 | ;; 81 | esac 82 | 83 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 84 | 85 | 86 | # Determine the Java command to use to start the JVM. 87 | if [ -n "$JAVA_HOME" ] ; then 88 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 89 | # IBM's JDK on AIX uses strange locations for the executables 90 | JAVACMD="$JAVA_HOME/jre/sh/java" 91 | else 92 | JAVACMD="$JAVA_HOME/bin/java" 93 | fi 94 | if [ ! -x "$JAVACMD" ] ; then 95 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 96 | 97 | Please set the JAVA_HOME variable in your environment to match the 98 | location of your Java installation." 99 | fi 100 | else 101 | JAVACMD="java" 102 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 103 | 104 | Please set the JAVA_HOME variable in your environment to match the 105 | location of your Java installation." 106 | fi 107 | 108 | # Increase the maximum file descriptors if we can. 109 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 110 | MAX_FD_LIMIT=`ulimit -H -n` 111 | if [ $? -eq 0 ] ; then 112 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 113 | MAX_FD="$MAX_FD_LIMIT" 114 | fi 115 | ulimit -n $MAX_FD 116 | if [ $? -ne 0 ] ; then 117 | warn "Could not set maximum file descriptor limit: $MAX_FD" 118 | fi 119 | else 120 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 121 | fi 122 | fi 123 | 124 | # For Darwin, add options to specify how the application appears in the dock 125 | if $darwin; then 126 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 127 | fi 128 | 129 | # For Cygwin or MSYS, switch paths to Windows format before running java 130 | if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then 131 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 132 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 133 | 134 | JAVACMD=`cygpath --unix "$JAVACMD"` 135 | 136 | # We build the pattern for arguments to be converted via cygpath 137 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 138 | SEP="" 139 | for dir in $ROOTDIRSRAW ; do 140 | ROOTDIRS="$ROOTDIRS$SEP$dir" 141 | SEP="|" 142 | done 143 | OURCYGPATTERN="(^($ROOTDIRS))" 144 | # Add a user-defined pattern to the cygpath arguments 145 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 146 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 147 | fi 148 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 149 | i=0 150 | for arg in "$@" ; do 151 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 152 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 153 | 154 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 155 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 156 | else 157 | eval `echo args$i`="\"$arg\"" 158 | fi 159 | i=`expr $i + 1` 160 | done 161 | case $i in 162 | 0) set -- ;; 163 | 1) set -- "$args0" ;; 164 | 2) set -- "$args0" "$args1" ;; 165 | 3) set -- "$args0" "$args1" "$args2" ;; 166 | 4) set -- "$args0" "$args1" "$args2" "$args3" ;; 167 | 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 168 | 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 169 | 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 170 | 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 171 | 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 172 | esac 173 | fi 174 | 175 | # Escape application args 176 | save () { 177 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done 178 | echo " " 179 | } 180 | APP_ARGS=`save "$@"` 181 | 182 | # Collect all arguments for the java command, following the shell quoting and substitution rules 183 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" 184 | 185 | exec "$JAVACMD" "$@" 186 | -------------------------------------------------------------------------------- /forge/build.gradle: -------------------------------------------------------------------------------- 1 | import org.codehaus.plexus.util.Os 2 | 3 | buildscript { 4 | repositories { 5 | maven { url = 'https://files.minecraftforge.net/maven' } 6 | jcenter() 7 | mavenCentral() 8 | maven { url='https://repo.spongepowered.org/maven' } 9 | } 10 | dependencies { 11 | classpath group: 'net.minecraftforge.gradle', name: 'ForgeGradle', version: '5.1.+', changing: true 12 | classpath group: 'org.spongepowered', name: 'mixingradle', version: '0.7-SNAPSHOT' 13 | } 14 | } 15 | apply plugin: 'net.minecraftforge.gradle' 16 | // Only edit below this line, the above code adds and enables the necessary things for Forge to be setup. 17 | apply plugin: 'eclipse' 18 | apply plugin: 'maven-publish' 19 | apply plugin: 'org.spongepowered.mixin' 20 | 21 | version = '4.0.4' 22 | group = 'jp.axer.cocoainput' // http://maven.apache.org/guides/mini/guide-naming-conventions.html 23 | archivesBaseName = 'CocoaInput-1.18-forge' 24 | 25 | // Mojang ships Java 16 to end users in 1.17+ instead of Java 8 in 1.16 or lower, so your mod should target Java 16. 26 | java.toolchain.languageVersion = JavaLanguageVersion.of(17) 27 | 28 | println('Java: ' + System.getProperty('java.version') + ' JVM: ' + System.getProperty('java.vm.version') + '(' + System.getProperty('java.vendor') + ') Arch: ' + System.getProperty('os.arch')) 29 | minecraft { 30 | // The mappings can be changed at any time, and must be in the following format. 31 | // snapshot_YYYYMMDD Snapshot are built nightly. 32 | // stable_# Stables are built at the discretion of the MCP team. 33 | // Use non-default mappings at your own risk. they may not always work. 34 | // Simply re-run your setup task after changing the mappings to update your workspace. 35 | mappings channel: 'official', version: '1.18' 36 | // makeObfSourceJar = false // an Srg named sources jar is made by default. uncomment this to disable. 37 | 38 | // accessTransformer = file('build/resources/main/META-INF/accesstransformer.cfg') 39 | accessTransformer = file('../src/forge/resources/META-INF/accesstransformer.cfg') 40 | 41 | // Default run configurations. 42 | // These can be tweaked, removed, or duplicated as needed. 43 | runs { 44 | client { 45 | workingDirectory project.file('run') 46 | 47 | // Recommended logging data for a userdev environment 48 | property 'forge.logging.markers', 'SCAN,REGISTRIES,REGISTRYDUMP' 49 | 50 | // Recommended logging level for the console 51 | property 'forge.logging.console.level', 'debug' 52 | arg "-mixin.config=cocoainput.mixins.json" 53 | 54 | sourceSets.main.java.srcDirs+=['../src/forge/java'] 55 | sourceSets.main.java.srcDirs+=['../src/main/java'] 56 | sourceSets.main.resources.srcDirs+=['../src/forge/resources'] 57 | sourceSets.main.resources.srcDirs+=['../src/main/resources'] 58 | mods { 59 | examplemod { 60 | source sourceSets.main 61 | } 62 | } 63 | } 64 | 65 | server { 66 | workingDirectory project.file('run') 67 | 68 | // Recommended logging data for a userdev environment 69 | property 'forge.logging.markers', 'SCAN,REGISTRIES,REGISTRYDUMP' 70 | 71 | // Recommended logging level for the console 72 | property 'forge.logging.console.level', 'debug' 73 | 74 | mods { 75 | examplemod { 76 | source sourceSets.main 77 | } 78 | } 79 | } 80 | } 81 | } 82 | 83 | mixin { 84 | add sourceSets.main, "cocoainput.refmap.json" 85 | } 86 | 87 | dependencies { 88 | // Specify the version of Minecraft to use, If this is any group other then 'net.minecraft' it is assumed 89 | // that the dep is a ForgeGradle 'patcher' dependency. And it's patches will be applied. 90 | // The userdev artifact is a special name and will get all sorts of transformations applied to it. 91 | minecraft 'net.minecraftforge:forge:1.18-38.0.15' 92 | 93 | // You may put jars on which you depend on in ./libs or you may define them like so.. 94 | // compile "some.group:artifact:version:classifier" 95 | // compile "some.group:artifact:version" 96 | 97 | // Real examples 98 | // compile 'com.mod-buildcraft:buildcraft:6.0.8:dev' // adds buildcraft to the dev env 99 | // compile 'com.googlecode.efficient-java-matrix-library:ejml:0.24' // adds ejml to the dev env 100 | 101 | // The 'provided' configuration is for optional dependencies that exist at compile-time but might not at runtime. 102 | // provided 'com.mod-buildcraft:buildcraft:6.0.8:dev' 103 | 104 | // These dependencies get remapped to your current MCP mappings 105 | // deobf 'com.mod-buildcraft:buildcraft:6.0.8:dev' 106 | 107 | // For more info... 108 | // http://www.gradle.org/docs/current/userguide/artifact_dependencies_tutorial.html 109 | // http://www.gradle.org/docs/current/userguide/dependency_management.html 110 | annotationProcessor 'org.spongepowered:mixin:0.8.4:processor' 111 | 112 | } 113 | 114 | 115 | // Example for how to get properties into the manifest for reading by the runtime.. 116 | jar { 117 | manifest { 118 | attributes([ 119 | "Specification-Title": "CocoaInput", 120 | "Specification-Vendor": "Axeryok", 121 | "Specification-Version": "1", // We are version 1 of ourselves 122 | "Implementation-Title": project.name, 123 | "Implementation-Version": "${version}", 124 | "Implementation-Vendor" :"Axeryok", 125 | "Implementation-Timestamp": new Date().format("yyyy-MM-dd'T'HH:mm:ssZ"), 126 | "MixinConfigs":"cocoainput.mixins.json" 127 | ]) 128 | } 129 | } 130 | 131 | // Example configuration to allow publishing using the maven-publish task 132 | // This is the preferred method to reobfuscate your jar file 133 | jar.finalizedBy('reobfJar') 134 | // However if you are in a multi-project build, dev time needs unobfed jar files, so you can delay the obfuscation until publishing by doing 135 | //publish.dependsOn('reobfJar') 136 | 137 | publishing { 138 | publications { 139 | mavenJava(MavenPublication) { 140 | artifact jar 141 | } 142 | } 143 | repositories { 144 | maven { 145 | url "file:///${project.projectDir}/mcmodsrepo" 146 | } 147 | } 148 | } 149 | 150 | -------------------------------------------------------------------------------- /libcocoainput/darwin/libcocoainput/DataManager.m: -------------------------------------------------------------------------------- 1 | // 2 | // DataManager.m 3 | // libcocoainput 4 | // 5 | // Created by Axer on 2019/03/23. 6 | // Copyright © 2019年 Axer. All rights reserved. 7 | // 8 | 9 | #import "DataManager.h" 10 | #import "cocoainput.h" 11 | #import "Logger.h" 12 | 13 | #define SPLIT_NSRANGE(x) (int)(x.location), (int)(x.length) 14 | 15 | static DataManager* instance = nil; 16 | 17 | @implementation DataManager 18 | 19 | @synthesize hasPreeditText; 20 | @synthesize isSentedInsertText; 21 | @synthesize isBeforeActionSetMarkedText; 22 | 23 | + (instancetype)sharedManager { 24 | if (!instance) { 25 | instance = [[DataManager alloc] init]; 26 | } 27 | return instance; 28 | } 29 | 30 | - (id)init { 31 | CIDebug(@"Textfield table has been initialized."); 32 | self = [super init]; 33 | self.hasPreeditText=NO; 34 | self.dic = [NSMutableDictionary dictionary]; 35 | self.activeView = nil; 36 | return self; 37 | } 38 | 39 | - (void) modifyGLFWView{ 40 | NSView *view; 41 | while(1){ 42 | view=[[NSApp keyWindow] contentView]; 43 | if([[view className]isEqualToString:@"GLFWContentView"]==YES)break; 44 | } 45 | [[DataManager sharedManager] setGlfwView:view]; 46 | replaceInstanceMethod([view class], @selector(keyDown:), @selector(org_keyDown:), [[DataManager sharedManager] class]); 47 | replaceInstanceMethod([view class], @selector(hasMarkedText), @selector(org_hasMarkedText), [[DataManager sharedManager] class]); 48 | replaceInstanceMethod([view class], @selector(markedRange), @selector(org_markedRange), [[DataManager sharedManager] class]); 49 | replaceInstanceMethod([view class], @selector(interpretKeyEvents:), @selector(org_interpretKeyEvents:), [[DataManager sharedManager] class]); 50 | replaceInstanceMethod([view class], @selector(insertText:replacementRange:), @selector(org_insertText:replacementRange:), [[DataManager sharedManager] class]); 51 | replaceInstanceMethod([view class],@selector(firstRectForCharacterRange:actualRange:),@selector(org_firstRectForCharacterRange:actualRange:),[[DataManager sharedManager] class]); 52 | replaceInstanceMethod([view class], @selector(setMarkedText:selectedRange:replacementRange:), @selector(org_setMarkedText:selectedRange:replacementRange:), [[DataManager sharedManager] class]); 53 | replaceInstanceMethod([view class], @selector(unmarkText), @selector(org_unmarkText), [[DataManager sharedManager] class]); 54 | CILog(@"Complete to modify GLFWView"); 55 | } 56 | 57 | - (void)keyDown:(NSEvent*)theEvent {//GLFWContentView改変用 58 | //見づらすぎて改修しづらい 59 | if ([DataManager sharedManager].activeView != nil ){ 60 | CIDebug(@"New keyEvent came and sent to textfield."); 61 | [self org_interpretKeyEvents:@[ theEvent ]]; 62 | } 63 | //NSLog(@"keydown %d %d %d\n",[DataManager sharedManager].hasPreeditText,[DataManager sharedManager].isSentedInsertText,[DataManager sharedManager].isBeforeActionSetMarkedText); 64 | if ([DataManager sharedManager].hasPreeditText==NO&&[DataManager sharedManager].isSentedInsertText==NO&&[DataManager sharedManager].isBeforeActionSetMarkedText==NO){ 65 | CIDebug(@"New keyEvent came and sent to original keyDown."); 66 | [self org_keyDown:theEvent]; 67 | } 68 | [DataManager sharedManager].isSentedInsertText = NO; 69 | [DataManager sharedManager].isBeforeActionSetMarkedText = NO; 70 | } 71 | 72 | - (void)interpretKeyEvents:(NSArray*)eventArray{//GLFWContentView改変用 73 | ; 74 | } 75 | 76 | - (void)unmarkText { 77 | [DataManager sharedManager].isBeforeActionSetMarkedText = YES; 78 | [DataManager sharedManager].hasPreeditText = NO; 79 | [self org_unmarkText]; 80 | } 81 | 82 | //確定文字列 (漢字変換を通さなかったものもここに入る) 83 | - (void)insertText:(id)aString replacementRange:(NSRange)replacementRange { 84 | if (![DataManager sharedManager].hasPreeditText) { 85 | [DataManager sharedManager].isSentedInsertText = NO; 86 | [self org_insertText:aString replacementRange:replacementRange]; 87 | return; 88 | } 89 | [DataManager sharedManager].hasPreeditText = NO; 90 | [DataManager sharedManager].isSentedInsertText = YES; 91 | /*const char *sentString; 92 | if ([aString isKindOfClass:[NSAttributedString class]]) { 93 | sentString = [[aString string] cStringUsingEncoding:NSUTF8StringEncoding]; 94 | } 95 | else{ 96 | sentString = [aString cStringUsingEncoding:NSUTF8StringEncoding]; 97 | }*/ 98 | [[DataManager sharedManager] activeView].insertText("",0,0); 99 | CIDebug([NSString stringWithFormat:@"MarkedText was determined:\"%@\"",aString]); 100 | [self org_insertText:aString replacementRange:replacementRange];//GLFWのオリジナルメソッドはCharEventを発行するので利用する 101 | } 102 | 103 | //漢字変換途中経過 104 | - (void)setMarkedText:(id)aString 105 | selectedRange:(NSRange)selectedRange 106 | replacementRange:(NSRange)replacementRange { 107 | [DataManager sharedManager].hasPreeditText = YES; 108 | NSString* debugText = aString; 109 | const char* sentString; 110 | if ([aString isKindOfClass:[NSAttributedString class]]) { 111 | sentString = [[aString string] cStringUsingEncoding:NSUTF8StringEncoding]; 112 | debugText = [aString string]; 113 | } else { 114 | sentString = [aString cStringUsingEncoding:NSUTF8StringEncoding]; 115 | } 116 | CIDebug([NSString stringWithFormat:@"MarkedText changed:\"%@\"", [aString description]]); 117 | [[DataManager sharedManager] activeView].setMarkedText(sentString, SPLIT_NSRANGE(selectedRange), 118 | SPLIT_NSRANGE(replacementRange)); 119 | [self org_setMarkedText:aString selectedRange:selectedRange replacementRange:replacementRange]; 120 | } 121 | 122 | - (NSRect)firstRectForCharacterRange:(NSRange)aRange 123 | actualRange:(NSRangePointer)actualRange { 124 | CIDebug(@"Called to determine where to draw."); 125 | if ([DataManager sharedManager].hasPreeditText == NO) { 126 | return [self org_firstRectForCharacterRange:aRange actualRange:actualRange]; 127 | } 128 | float* rect = [[DataManager sharedManager] activeView].firstRectForCharacterRange(); 129 | NSRect lwjgl = [self org_firstRectForCharacterRange:aRange actualRange:actualRange];//GLFWのオリジナルを呼び出すとウィンドウのポジションが得られるので利用する 130 | return NSMakeRect(rect[0]+lwjgl.origin.x, 131 | [[[DataManager sharedManager] glfwView] frame].size.height-rect[1]+lwjgl.origin.y, 132 | rect[2], 133 | rect[3]); 134 | } 135 | 136 | - (BOOL)hasMarkedText { 137 | return NO; 138 | } 139 | 140 | - (NSRange)selectedRange { 141 | return NSMakeRange(NSNotFound, 0); 142 | } 143 | 144 | - (NSRange)markedRange { 145 | [[DataManager sharedManager] activeView].insertText("", 0, 0); 146 | [self unmarkText]; 147 | return NSMakeRange(NSNotFound, 0); 148 | } 149 | 150 | - (NSArray*)validAttributesForMarkedText { 151 | return nil; 152 | } 153 | 154 | - (NSAttributedString*)attributedSubstringForProposedRange:(NSRange)aRange 155 | actualRange: 156 | (NSRangePointer)actualRange { 157 | return nil; 158 | } 159 | 160 | - (NSUInteger)characterIndexForPoint:(NSPoint)aPoint { 161 | return 0; 162 | } 163 | 164 | - (void)doCommandBySelector:(nonnull SEL)selector { 165 | } 166 | 167 | 168 | // 警告消しのためのダミーメソッド 169 | - (NSRange)org_markedRange{return NSMakeRange(NSNotFound, 0);} 170 | - (BOOL)org_hasMarkedText{return YES;}; 171 | - (void)org_keyDown:(NSEvent*)theEvent{} 172 | - (void)org_unmarkText{} 173 | - (void)org_interpretKeyEvents:(NSArray*)eventArray{} 174 | - (NSRect)org_firstRectForCharacterRange:(NSRange)aRange 175 | actualRange:(NSRangePointer)actualRange{return NSMakeRect(0,0,0,0);} 176 | - (void)org_insertText:(id)aString replacementRange:(NSRange)replacementRange{} 177 | - (void)org_setMarkedText:(id)aString 178 | selectedRange:(NSRange)selectedRange 179 | replacementRange:(NSRange)replacementRange {} 180 | 181 | 182 | @end 183 | -------------------------------------------------------------------------------- /src/main/java/jp/axer/cocoainput/util/TinyConfig.java: -------------------------------------------------------------------------------- 1 | package jp.axer.cocoainput.util; 2 | import java.lang.annotation.ElementType; 3 | import java.lang.annotation.Retention; 4 | import java.lang.annotation.RetentionPolicy; 5 | import java.lang.annotation.Target; 6 | import java.lang.reflect.Field; 7 | import java.lang.reflect.Method; 8 | import java.lang.reflect.Modifier; 9 | import java.nio.file.Files; 10 | import java.nio.file.Path; 11 | import java.util.AbstractMap; 12 | import java.util.ArrayList; 13 | import java.util.Arrays; 14 | import java.util.List; 15 | import java.util.Map; 16 | import java.util.function.BiFunction; 17 | import java.util.function.Function; 18 | import java.util.function.Predicate; 19 | import java.util.regex.Pattern; 20 | 21 | import com.google.gson.Gson; 22 | import com.google.gson.GsonBuilder; 23 | import com.mojang.blaze3d.vertex.PoseStack; 24 | 25 | import net.minecraft.client.gui.screens.Screen; 26 | import net.minecraft.client.gui.components.EditBox; 27 | import net.minecraft.client.gui.components.Button; 28 | import net.minecraft.network.chat.BaseComponent; 29 | import net.minecraft.network.chat.TextComponent; 30 | import net.minecraft.network.chat.TranslatableComponent; 31 | 32 | public class TinyConfig { 33 | 34 | private static final Pattern INTEGER_ONLY = Pattern.compile("(-?[0-9]*)"); 35 | private static final Pattern DECIMAL_ONLY = Pattern.compile("-?([\\d]+\\.?[\\d]*|[\\d]*\\.?[\\d]+|\\.)"); 36 | 37 | private static final List entries = new ArrayList<>(); 38 | 39 | protected static class EntryInfo { 40 | Field field; 41 | Object widget; 42 | int width; 43 | String comment; 44 | Method dynamicTooltip; 45 | Map.Entry error; 46 | Object defaultValue; 47 | Object value; 48 | String tempValue; 49 | boolean inLimits = true; 50 | } 51 | 52 | private static Class configClass; 53 | private static String translationPrefix; 54 | private static Path path; 55 | 56 | private static final Gson gson = new GsonBuilder() 57 | .excludeFieldsWithModifiers(Modifier.TRANSIENT) 58 | .excludeFieldsWithModifiers(Modifier.PRIVATE) 59 | .setPrettyPrinting() 60 | .create(); 61 | 62 | public static void init(String modid,Path apath, Class config) { 63 | translationPrefix = modid + ".tinyconfig."; 64 | configClass = config; 65 | path=apath; 66 | 67 | for (Field field : config.getFields()) { 68 | Entry e; 69 | try { e = field.getAnnotation(Entry.class); } 70 | catch (Exception ignored) { continue; } 71 | if(e==null) {continue;} 72 | Class type = field.getType(); 73 | EntryInfo info = new EntryInfo(); 74 | info.width = e.width(); 75 | info.field = field; 76 | 77 | if (type == int.class) textField(info, Integer::parseInt, INTEGER_ONLY, e.min(), e.max(), true); 78 | else if (type == double.class) textField(info, Double::parseDouble, DECIMAL_ONLY, e.min(), e.max(),false); 79 | else if (type == String.class) textField(info, String::length, null, Math.min(e.min(),0), Math.max(e.max(),1),true); 80 | else if (type == boolean.class) { 81 | Function func = value -> new TextComponent((Boolean) value ? "True" : "False"); 82 | info.widget = new AbstractMap.SimpleEntry>(button -> { 83 | info.value = !(Boolean) info.value; 84 | button.setMessage(func.apply(info.value)); 85 | }, func); 86 | } 87 | else if (type.isEnum()) { 88 | List values = Arrays.asList(field.getType().getEnumConstants()); 89 | Function func = value -> new TranslatableComponent(translationPrefix + "enum." + type.getSimpleName() + "." + info.value.toString()); 90 | info.widget = new AbstractMap.SimpleEntry>( button -> { 91 | int index = values.indexOf(info.value) + 1; 92 | info.value = values.get(index >= values.size()? 0 : index); 93 | button.setMessage(func.apply(info.value)); 94 | }, func); 95 | } 96 | else 97 | continue; 98 | 99 | entries.add(info); 100 | 101 | try { info.defaultValue = field.get(null); } 102 | catch (IllegalAccessException ignored) {} 103 | 104 | try { 105 | info.dynamicTooltip = config.getMethod(e.dynamicTooltip()); 106 | info.dynamicTooltip.setAccessible(true); 107 | } catch (Exception ignored) {} 108 | info.comment=e.comment(); 109 | } 110 | 111 | try { gson.fromJson(Files.newBufferedReader(path), config); } 112 | catch (Exception e) { write(); } 113 | 114 | for (EntryInfo info : entries) { 115 | try { 116 | info.value = info.field.get(null); 117 | info.tempValue = info.value.toString(); 118 | } 119 | catch (IllegalAccessException ignored) {} 120 | } 121 | 122 | } 123 | 124 | private static void textField(EntryInfo info, Function f, Pattern pattern, double min, double max, boolean cast) { 125 | boolean isNumber = pattern != null; 126 | info.widget = (BiFunction>) (t, b) -> s -> { 127 | s = s.trim(); 128 | if (!(s.isEmpty() || !isNumber || pattern.matcher(s).matches())) 129 | return false; 130 | 131 | Number value = 0; 132 | boolean inLimits = false; 133 | System.out.println(((isNumber ^ s.isEmpty()))); 134 | System.out.println(!s.equals("-") && !s.equals(".")); 135 | info.error = null; 136 | if (!(isNumber && s.isEmpty()) && !s.equals("-") && !s.equals(".")) { 137 | value = f.apply(s); 138 | inLimits = value.doubleValue() >= min && value.doubleValue() <= max; 139 | info.error = inLimits? null : new AbstractMap.SimpleEntry<>(t, new TextComponent(value.doubleValue() < min ? 140 | "§cMinimum " + (isNumber? "value" : "length") + (cast? " is " + (int)min : " is " + min) : 141 | "§cMaximum " + (isNumber? "value" : "length") + (cast? " is " + (int)max : " is " + max))); 142 | } 143 | 144 | info.tempValue = s; 145 | t.setTextColor(inLimits? 0xFFFFFFFF : 0xFFFF7777); 146 | info.inLimits = inLimits; 147 | b.active = entries.stream().allMatch(e -> e.inLimits); 148 | 149 | if (inLimits) 150 | info.value = isNumber? value : s; 151 | 152 | return true; 153 | }; 154 | } 155 | 156 | public static void write() { 157 | try { 158 | if (!Files.exists(path)) Files.createFile(path); 159 | Files.write(path, gson.toJson(configClass.newInstance()).getBytes()); 160 | } catch (Exception e) { 161 | e.printStackTrace(); 162 | } 163 | 164 | } 165 | 166 | public Screen getScreen(Screen parent) { 167 | return new TinyConfigScreen(parent); 168 | } 169 | 170 | private static class TinyConfigScreen extends Screen { 171 | protected TinyConfigScreen(Screen parent) { 172 | super(new TextComponent("CocoaInput config")); 173 | this.parent = parent; 174 | } 175 | private final Screen parent; 176 | 177 | @Override 178 | protected void init() { 179 | super.init(); 180 | 181 | Button done = this.addRenderableWidget(new Button(this.width/2 - 100,this.height - 28,200,20, 182 | new TranslatableComponent("gui.done"), (button) -> { 183 | for (EntryInfo info : entries) 184 | try { info.field.set(null, info.value); } 185 | catch (IllegalAccessException ignore) {} 186 | write(); 187 | minecraft.setScreen(parent); 188 | })); 189 | 190 | int y = 45; 191 | for (EntryInfo info : entries) { 192 | if (info.widget instanceof Map.Entry) { 193 | Map.Entry> widget = (Map.Entry>) info.widget; 194 | addRenderableWidget(new Button(width-85,y,info.width,20, widget.getValue().apply(info.value), widget.getKey())); 195 | } 196 | else { 197 | EditBox widget = addWidget(new EditBox(font, width-85, y, info.width, 20, null)); 198 | widget.setValue(info.tempValue); 199 | 200 | Predicate processor = ((BiFunction>) info.widget).apply(widget,done); 201 | widget.setFilter(processor); 202 | processor.test(info.tempValue); 203 | 204 | addWidget(widget); 205 | } 206 | y += 30; 207 | } 208 | 209 | } 210 | 211 | @Override 212 | public void render(PoseStack matrices, int mouseX, int mouseY, float delta) { 213 | this.renderBackground(matrices); 214 | 215 | if (mouseY >= 40 && mouseY <= 39 + entries.size()*30) { 216 | int low = ((mouseY-10)/30)*30 + 10 + 2; 217 | fill(matrices, 0, low, width, low+30-4, 0x33FFFFFF); 218 | } 219 | 220 | super.render(matrices, mouseX, mouseY, delta); 221 | drawCenteredString(matrices, font, title, width/2, 15, 0xFFFFFF); 222 | 223 | int y = 40; 224 | for (EntryInfo info : entries) { 225 | drawString(matrices, font, new TextComponent(info.comment), 12, y + 10, 0xFFFFFF); 226 | /* 227 | if (info.error != null && info.error.getKey().isMouseOver(mouseX,mouseY)) 228 | renderTooltip(matrices, info.error.getValue(), mouseX, mouseY); 229 | else if (mouseY >= y && mouseY < (y + 30)) { 230 | if (info.dynamicTooltip != null) { 231 | try { 232 | renderComponentTooltip(matrices, (List) info.dynamicTooltip.invoke(null, entries), mouseX, mouseY); 233 | y += 30; 234 | continue; 235 | } catch (Exception e) { e.printStackTrace(); } 236 | } 237 | String key = translationPrefix + info.field.getName() + ".tooltip"; 238 | 239 | List list = new ArrayList<>(); 240 | for (String str : I18n.get(key).split("\n")) 241 | list.add(new TextComponent(str)); 242 | renderComponentTooltip(matrices, list, mouseX, mouseY); 243 | 244 | } 245 | */ 246 | y += 30; 247 | } 248 | } 249 | } 250 | 251 | @Retention(RetentionPolicy.RUNTIME) 252 | @Target(ElementType.FIELD) 253 | public @interface Entry { 254 | String comment() default ""; 255 | String dynamicTooltip() default ""; 256 | int width() default 75; 257 | double min() default Double.MIN_NORMAL; 258 | double max() default Double.MAX_VALUE; 259 | } 260 | 261 | } -------------------------------------------------------------------------------- /libcocoainput/darwin/libcocoainput.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 50; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 7ADD32A12245DC09008BB7B1 /* cocoainput.h in Headers */ = {isa = PBXBuildFile; fileRef = 7ADD32A02245DC09008BB7B1 /* cocoainput.h */; }; 11 | 7ADD32A32245DC09008BB7B1 /* cocoainput.m in Sources */ = {isa = PBXBuildFile; fileRef = 7ADD32A22245DC09008BB7B1 /* cocoainput.m */; }; 12 | 7ADD32AA2245DE47008BB7B1 /* Logger.m in Sources */ = {isa = PBXBuildFile; fileRef = 7ADD32A92245DE47008BB7B1 /* Logger.m */; }; 13 | 7ADD32AE2245DFF2008BB7B1 /* DataManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 7ADD32AC2245DFF2008BB7B1 /* DataManager.h */; }; 14 | 7ADD32AF2245DFF2008BB7B1 /* DataManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 7ADD32AD2245DFF2008BB7B1 /* DataManager.m */; }; 15 | 7ADD32B22245E11E008BB7B1 /* MinecraftView.h in Headers */ = {isa = PBXBuildFile; fileRef = 7ADD32B02245E11E008BB7B1 /* MinecraftView.h */; }; 16 | 7ADD32B32245E11E008BB7B1 /* MinecraftView.m in Sources */ = {isa = PBXBuildFile; fileRef = 7ADD32B12245E11E008BB7B1 /* MinecraftView.m */; }; 17 | 7ADD32B522479964008BB7B1 /* Makefile in Sources */ = {isa = PBXBuildFile; fileRef = 7ADD32B422479964008BB7B1 /* Makefile */; }; 18 | /* End PBXBuildFile section */ 19 | 20 | /* Begin PBXFileReference section */ 21 | 7ADD329D2245DC09008BB7B1 /* libcocoainput.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = libcocoainput.dylib; sourceTree = BUILT_PRODUCTS_DIR; }; 22 | 7ADD32A02245DC09008BB7B1 /* cocoainput.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = cocoainput.h; sourceTree = ""; }; 23 | 7ADD32A22245DC09008BB7B1 /* cocoainput.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = cocoainput.m; sourceTree = ""; }; 24 | 7ADD32A92245DE47008BB7B1 /* Logger.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = Logger.m; sourceTree = ""; }; 25 | 7ADD32AB2245DE53008BB7B1 /* Logger.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Logger.h; sourceTree = ""; }; 26 | 7ADD32AC2245DFF2008BB7B1 /* DataManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DataManager.h; sourceTree = ""; }; 27 | 7ADD32AD2245DFF2008BB7B1 /* DataManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = DataManager.m; sourceTree = ""; }; 28 | 7ADD32B02245E11E008BB7B1 /* MinecraftView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MinecraftView.h; sourceTree = ""; }; 29 | 7ADD32B12245E11E008BB7B1 /* MinecraftView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MinecraftView.m; sourceTree = ""; }; 30 | 7ADD32B422479964008BB7B1 /* Makefile */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.make; path = Makefile; sourceTree = ""; }; 31 | /* End PBXFileReference section */ 32 | 33 | /* Begin PBXFrameworksBuildPhase section */ 34 | 7ADD329A2245DC09008BB7B1 /* Frameworks */ = { 35 | isa = PBXFrameworksBuildPhase; 36 | buildActionMask = 2147483647; 37 | files = ( 38 | ); 39 | runOnlyForDeploymentPostprocessing = 0; 40 | }; 41 | /* End PBXFrameworksBuildPhase section */ 42 | 43 | /* Begin PBXGroup section */ 44 | 7ADD32942245DC09008BB7B1 = { 45 | isa = PBXGroup; 46 | children = ( 47 | 7ADD329F2245DC09008BB7B1 /* libcocoainput */, 48 | 7ADD329E2245DC09008BB7B1 /* Products */, 49 | ); 50 | sourceTree = ""; 51 | }; 52 | 7ADD329E2245DC09008BB7B1 /* Products */ = { 53 | isa = PBXGroup; 54 | children = ( 55 | 7ADD329D2245DC09008BB7B1 /* libcocoainput.dylib */, 56 | ); 57 | name = Products; 58 | sourceTree = ""; 59 | }; 60 | 7ADD329F2245DC09008BB7B1 /* libcocoainput */ = { 61 | isa = PBXGroup; 62 | children = ( 63 | 7ADD32A02245DC09008BB7B1 /* cocoainput.h */, 64 | 7ADD32A22245DC09008BB7B1 /* cocoainput.m */, 65 | 7ADD32AB2245DE53008BB7B1 /* Logger.h */, 66 | 7ADD32A92245DE47008BB7B1 /* Logger.m */, 67 | 7ADD32AC2245DFF2008BB7B1 /* DataManager.h */, 68 | 7ADD32AD2245DFF2008BB7B1 /* DataManager.m */, 69 | 7ADD32B02245E11E008BB7B1 /* MinecraftView.h */, 70 | 7ADD32B12245E11E008BB7B1 /* MinecraftView.m */, 71 | 7ADD32B422479964008BB7B1 /* Makefile */, 72 | ); 73 | path = libcocoainput; 74 | sourceTree = ""; 75 | }; 76 | /* End PBXGroup section */ 77 | 78 | /* Begin PBXHeadersBuildPhase section */ 79 | 7ADD329B2245DC09008BB7B1 /* Headers */ = { 80 | isa = PBXHeadersBuildPhase; 81 | buildActionMask = 2147483647; 82 | files = ( 83 | 7ADD32AE2245DFF2008BB7B1 /* DataManager.h in Headers */, 84 | 7ADD32B22245E11E008BB7B1 /* MinecraftView.h in Headers */, 85 | 7ADD32A12245DC09008BB7B1 /* cocoainput.h in Headers */, 86 | ); 87 | runOnlyForDeploymentPostprocessing = 0; 88 | }; 89 | /* End PBXHeadersBuildPhase section */ 90 | 91 | /* Begin PBXNativeTarget section */ 92 | 7ADD329C2245DC09008BB7B1 /* libcocoainput */ = { 93 | isa = PBXNativeTarget; 94 | buildConfigurationList = 7ADD32A62245DC09008BB7B1 /* Build configuration list for PBXNativeTarget "libcocoainput" */; 95 | buildPhases = ( 96 | 7ADD32992245DC09008BB7B1 /* Sources */, 97 | 7ADD329A2245DC09008BB7B1 /* Frameworks */, 98 | 7ADD329B2245DC09008BB7B1 /* Headers */, 99 | ); 100 | buildRules = ( 101 | ); 102 | dependencies = ( 103 | ); 104 | name = libcocoainput; 105 | productName = libcocoainput; 106 | productReference = 7ADD329D2245DC09008BB7B1 /* libcocoainput.dylib */; 107 | productType = "com.apple.product-type.library.dynamic"; 108 | }; 109 | /* End PBXNativeTarget section */ 110 | 111 | /* Begin PBXProject section */ 112 | 7ADD32952245DC09008BB7B1 /* Project object */ = { 113 | isa = PBXProject; 114 | attributes = { 115 | LastUpgradeCheck = 0930; 116 | ORGANIZATIONNAME = Axer; 117 | TargetAttributes = { 118 | 7ADD329C2245DC09008BB7B1 = { 119 | CreatedOnToolsVersion = 9.3; 120 | }; 121 | }; 122 | }; 123 | buildConfigurationList = 7ADD32982245DC09008BB7B1 /* Build configuration list for PBXProject "libcocoainput" */; 124 | compatibilityVersion = "Xcode 9.3"; 125 | developmentRegion = en; 126 | hasScannedForEncodings = 0; 127 | knownRegions = ( 128 | en, 129 | ); 130 | mainGroup = 7ADD32942245DC09008BB7B1; 131 | productRefGroup = 7ADD329E2245DC09008BB7B1 /* Products */; 132 | projectDirPath = ""; 133 | projectRoot = ""; 134 | targets = ( 135 | 7ADD329C2245DC09008BB7B1 /* libcocoainput */, 136 | ); 137 | }; 138 | /* End PBXProject section */ 139 | 140 | /* Begin PBXSourcesBuildPhase section */ 141 | 7ADD32992245DC09008BB7B1 /* Sources */ = { 142 | isa = PBXSourcesBuildPhase; 143 | buildActionMask = 2147483647; 144 | files = ( 145 | 7ADD32B522479964008BB7B1 /* Makefile in Sources */, 146 | 7ADD32A32245DC09008BB7B1 /* cocoainput.m in Sources */, 147 | 7ADD32AF2245DFF2008BB7B1 /* DataManager.m in Sources */, 148 | 7ADD32B32245E11E008BB7B1 /* MinecraftView.m in Sources */, 149 | 7ADD32AA2245DE47008BB7B1 /* Logger.m in Sources */, 150 | ); 151 | runOnlyForDeploymentPostprocessing = 0; 152 | }; 153 | /* End PBXSourcesBuildPhase section */ 154 | 155 | /* Begin XCBuildConfiguration section */ 156 | 7ADD32A42245DC09008BB7B1 /* Debug */ = { 157 | isa = XCBuildConfiguration; 158 | buildSettings = { 159 | ALWAYS_SEARCH_USER_PATHS = NO; 160 | CLANG_ANALYZER_NONNULL = YES; 161 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 162 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 163 | CLANG_CXX_LIBRARY = "libc++"; 164 | CLANG_ENABLE_MODULES = YES; 165 | CLANG_ENABLE_OBJC_ARC = YES; 166 | CLANG_ENABLE_OBJC_WEAK = YES; 167 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 168 | CLANG_WARN_BOOL_CONVERSION = YES; 169 | CLANG_WARN_COMMA = YES; 170 | CLANG_WARN_CONSTANT_CONVERSION = YES; 171 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 172 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 173 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 174 | CLANG_WARN_EMPTY_BODY = YES; 175 | CLANG_WARN_ENUM_CONVERSION = YES; 176 | CLANG_WARN_INFINITE_RECURSION = YES; 177 | CLANG_WARN_INT_CONVERSION = YES; 178 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 179 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 180 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 181 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 182 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 183 | CLANG_WARN_STRICT_PROTOTYPES = YES; 184 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 185 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 186 | CLANG_WARN_UNREACHABLE_CODE = YES; 187 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 188 | CODE_SIGN_IDENTITY = "-"; 189 | COPY_PHASE_STRIP = NO; 190 | DEBUG_INFORMATION_FORMAT = dwarf; 191 | ENABLE_STRICT_OBJC_MSGSEND = YES; 192 | ENABLE_TESTABILITY = YES; 193 | GCC_C_LANGUAGE_STANDARD = gnu11; 194 | GCC_DYNAMIC_NO_PIC = NO; 195 | GCC_NO_COMMON_BLOCKS = YES; 196 | GCC_OPTIMIZATION_LEVEL = 0; 197 | GCC_PREPROCESSOR_DEFINITIONS = ( 198 | "DEBUG=1", 199 | "$(inherited)", 200 | ); 201 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 202 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 203 | GCC_WARN_UNDECLARED_SELECTOR = YES; 204 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 205 | GCC_WARN_UNUSED_FUNCTION = YES; 206 | GCC_WARN_UNUSED_VARIABLE = YES; 207 | MACOSX_DEPLOYMENT_TARGET = 10.13; 208 | MTL_ENABLE_DEBUG_INFO = YES; 209 | ONLY_ACTIVE_ARCH = YES; 210 | SDKROOT = macosx; 211 | }; 212 | name = Debug; 213 | }; 214 | 7ADD32A52245DC09008BB7B1 /* Release */ = { 215 | isa = XCBuildConfiguration; 216 | buildSettings = { 217 | ALWAYS_SEARCH_USER_PATHS = NO; 218 | CLANG_ANALYZER_NONNULL = YES; 219 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 220 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 221 | CLANG_CXX_LIBRARY = "libc++"; 222 | CLANG_ENABLE_MODULES = YES; 223 | CLANG_ENABLE_OBJC_ARC = YES; 224 | CLANG_ENABLE_OBJC_WEAK = YES; 225 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 226 | CLANG_WARN_BOOL_CONVERSION = YES; 227 | CLANG_WARN_COMMA = YES; 228 | CLANG_WARN_CONSTANT_CONVERSION = YES; 229 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 230 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 231 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 232 | CLANG_WARN_EMPTY_BODY = YES; 233 | CLANG_WARN_ENUM_CONVERSION = YES; 234 | CLANG_WARN_INFINITE_RECURSION = YES; 235 | CLANG_WARN_INT_CONVERSION = YES; 236 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 237 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 238 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 239 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 240 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 241 | CLANG_WARN_STRICT_PROTOTYPES = YES; 242 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 243 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 244 | CLANG_WARN_UNREACHABLE_CODE = YES; 245 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 246 | CODE_SIGN_IDENTITY = "-"; 247 | COPY_PHASE_STRIP = NO; 248 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 249 | ENABLE_NS_ASSERTIONS = NO; 250 | ENABLE_STRICT_OBJC_MSGSEND = YES; 251 | GCC_C_LANGUAGE_STANDARD = gnu11; 252 | GCC_NO_COMMON_BLOCKS = YES; 253 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 254 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 255 | GCC_WARN_UNDECLARED_SELECTOR = YES; 256 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 257 | GCC_WARN_UNUSED_FUNCTION = YES; 258 | GCC_WARN_UNUSED_VARIABLE = YES; 259 | MACOSX_DEPLOYMENT_TARGET = 10.13; 260 | MTL_ENABLE_DEBUG_INFO = NO; 261 | SDKROOT = macosx; 262 | }; 263 | name = Release; 264 | }; 265 | 7ADD32A72245DC09008BB7B1 /* Debug */ = { 266 | isa = XCBuildConfiguration; 267 | buildSettings = { 268 | CODE_SIGN_STYLE = Automatic; 269 | DYLIB_COMPATIBILITY_VERSION = 1; 270 | DYLIB_CURRENT_VERSION = 1; 271 | EXECUTABLE_PREFIX = ""; 272 | PRODUCT_NAME = "$(TARGET_NAME)"; 273 | SKIP_INSTALL = YES; 274 | }; 275 | name = Debug; 276 | }; 277 | 7ADD32A82245DC09008BB7B1 /* Release */ = { 278 | isa = XCBuildConfiguration; 279 | buildSettings = { 280 | CODE_SIGN_STYLE = Automatic; 281 | DYLIB_COMPATIBILITY_VERSION = 1; 282 | DYLIB_CURRENT_VERSION = 1; 283 | EXECUTABLE_PREFIX = ""; 284 | PRODUCT_NAME = "$(TARGET_NAME)"; 285 | SKIP_INSTALL = YES; 286 | }; 287 | name = Release; 288 | }; 289 | /* End XCBuildConfiguration section */ 290 | 291 | /* Begin XCConfigurationList section */ 292 | 7ADD32982245DC09008BB7B1 /* Build configuration list for PBXProject "libcocoainput" */ = { 293 | isa = XCConfigurationList; 294 | buildConfigurations = ( 295 | 7ADD32A42245DC09008BB7B1 /* Debug */, 296 | 7ADD32A52245DC09008BB7B1 /* Release */, 297 | ); 298 | defaultConfigurationIsVisible = 0; 299 | defaultConfigurationName = Release; 300 | }; 301 | 7ADD32A62245DC09008BB7B1 /* Build configuration list for PBXNativeTarget "libcocoainput" */ = { 302 | isa = XCConfigurationList; 303 | buildConfigurations = ( 304 | 7ADD32A72245DC09008BB7B1 /* Debug */, 305 | 7ADD32A82245DC09008BB7B1 /* Release */, 306 | ); 307 | defaultConfigurationIsVisible = 0; 308 | defaultConfigurationName = Release; 309 | }; 310 | /* End XCConfigurationList section */ 311 | }; 312 | rootObject = 7ADD32952245DC09008BB7B1 /* Project object */; 313 | } 314 | --------------------------------------------------------------------------------