Skip to content

Commit

Permalink
Adding RecordApi which provides a higher level api for reading record…
Browse files Browse the repository at this point in the history
…s with parsed XObjects so the user does not need to parse the data.

Each XObject now has a static PLUGIN_NAME assigned to the plugin name and an instance getter method.
Plugins now use the header as the plugin name.
Added all plugin info from the xml file (extensionName, extensionXName, extensionMultiword)
added methods to client for reading protocol from any X11Input. This is used for reading data from the record extension and for testing read/write for any object.
Fixed issues with list lengths which need to be unsigned.
  • Loading branch information
moaxcp committed Mar 8, 2024
1 parent 03ebdf5 commit 869173b
Show file tree
Hide file tree
Showing 54 changed files with 1,235 additions and 239 deletions.
1 change: 1 addition & 0 deletions .idea/.name

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 8 additions & 1 deletion .idea/compiler.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion .idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion .idea/modules.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 0 additions & 13 deletions .idea/modules/x11-client.integrationTest.iml

This file was deleted.

5 changes: 0 additions & 5 deletions .idea/modules/x11-client.main.iml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -448,10 +448,21 @@ https://p.janouch.name/article-xgb.html

https://jamey.thesharps.us/2021/03/25/xcb-protocol-specifications-data/

https://www.x.org/releases/X11R7.6/doc/libXtst/recordlib.html



# versions

## 0.15.0

* Adding RecordApi which provides a higher level api for reading records with parsed XObjects so the user does not need to parse the data.
* Each XObject now has a static PLUGIN_NAME assigned to the plugin name and an instance getter method.
* Plugins now use the header as the plugin name.
* Added all plugin info from the xml file (extensionName, extensionXName, extensionMultiword)
* added methods to client for reading protocol from any X11Input. This is used for reading data from the record extension and for testing read/write for any object.
* Fixed issues with list lengths which need to be unsigned.

## 0.14.0

* Fixed issue where WILD XAuthority entries do not have an address
Expand Down
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ plugins {
id 'jacoco'
}

version = '0.14.0'
version = '0.15.0'
group = 'com.github.moaxcp.x11'
description = 'An x11 client implemented in java'

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ class ProtocolGenerator {
}
}

writeToFile(result.javaPackage, result.getPluginXObjectInterface())
writeToFile(result.javaPackage, result.getXPlugin())

String pluginClass = result.pluginClassName.canonicalName()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ abstract class JavaClass implements JavaType {
result = map.result
basePackage = map.basePackage
javaPackage = map.javaPackage
superTypes = map.superTypes ? map.superTypes + ClassName.get(javaPackage, result.getPluginXObjectInterfaceName()) : [ClassName.get(javaPackage, result.getPluginXObjectInterfaceName())]
superTypes = map.superTypes ?: []
className = map.className
xUnitSubtype = map.xUnitSubtype
setProtocol(map.prtocol)
Expand Down Expand Up @@ -91,8 +91,16 @@ abstract class JavaClass implements JavaType {
TypeSpec getTypeSpec() {
TypeSpec.Builder typeSpec = TypeSpec.classBuilder(className)
typeSpec.addModifiers(Modifier.PUBLIC)
typeSpec.addField(FieldSpec.builder(String.class, 'PLUGIN_NAME', Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL)
.initializer('"$L"', result.header)
.build())
addFields(typeSpec)
addMethods(typeSpec)
typeSpec.addMethod(MethodSpec.methodBuilder('getPluginName')
.addModifiers(Modifier.PUBLIC)
.returns(String.class)
.addStatement('return PLUGIN_NAME')
.build())
if(superTypes) {
typeSpec.addSuperinterfaces(superTypes)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ class JavaEvent extends JavaClass {
javaEvent.protocol = event.toJavaProtocol(javaEvent)
JavaProperty p = javaEvent.getJavaProperty('NUMBER')
p.constantField = true
p.writeValueExpression = CodeBlock.of('sentEvent ? (byte) (0b10000000 & getResponseCode()) : getResponseCode()')
p.writeValueExpression = CodeBlock.of('sentEvent ? (byte) (0b10000000 | getResponseCode()) : getResponseCode()')
if (javaEvent.fixedSize && javaEvent.fixedSize.get() < 32) {
javaEvent.protocol.add(new JavaPad(javaClass: javaEvent, bytes: 32 - javaEvent.fixedSize.get()))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ class JavaPrimativeListProperty extends JavaListProperty {
@Override
CodeBlock getReadCode() {
if(lengthExpression instanceof EmptyExpression) {
return CodeBlock.of('in.read$L($L)', fromUpperUnderscoreToUpperCamel(x11Type), CodeBlock.of('javaStart - length'))
return CodeBlock.of('in.read$L($L)', fromUpperUnderscoreToUpperCamel(x11Type), CodeBlock.of('Short.toUnsignedInt(length) - javaStart'))
} else {
return CodeBlock.of('in.read$L($L)', fromUpperUnderscoreToUpperCamel(x11Type), lengthExpression.getExpression(TypeName.INT))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ class JavaTypeListProperty extends JavaListProperty {
lengthExpression = CodeBlock.of('Short.toUnsignedInt($L)', lengthProperty.name)
}
return CodeBlock.builder()
.addStatement('$1T $2L = new $3T<>(length - javaStart)', typeName, name, ArrayList.class)
.addStatement('$1T $2L = new $3T<>($4L - javaStart)', typeName, name, ArrayList.class, lengthExpression)
.beginControlFlow('while(javaStart < $L * 4)', lengthExpression)
.addStatement('$T baseObject = $L', baseTypeName, readObjectBlock)
.addStatement('$L.add(baseObject)', name)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import com.github.moaxcp.x11protocol.generator.Conventions
import com.squareup.javapoet.ClassName
import com.squareup.javapoet.FieldSpec
import com.squareup.javapoet.MethodSpec
import com.squareup.javapoet.ParameterizedTypeName
import com.squareup.javapoet.TypeSpec
import groovy.transform.EqualsAndHashCode
import groovy.transform.Memoized
Expand Down Expand Up @@ -50,44 +51,46 @@ class XResult {
return getJavaName(header.capitalize()) + 'Object'
}

TypeSpec getPluginXObjectInterface() {
TypeSpec.Builder builder = TypeSpec.interfaceBuilder(getPluginXObjectInterfaceName())
.addSuperinterface(ClassName.get(basePackage, 'XObject'))
.addMethod(MethodSpec.methodBuilder('getPluginName')
.returns(String.class)
.addModifiers(Modifier.DEFAULT, Modifier.PUBLIC)
.addStatement('return $T.NAME', getPluginClassName())
.build())
return builder.build()
}

TypeSpec getXPlugin() {
TypeSpec.Builder builder = TypeSpec.classBuilder(getPluginClassName())
.addModifiers(Modifier.PUBLIC)
.addSuperinterface(ClassName.get(basePackage, 'XProtocolPlugin'))

builder.addField(
FieldSpec.builder(String.class, 'NAME', Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL)
.initializer('"$L"', extensionXName)
.build())
builder.addMethod(MethodSpec.methodBuilder('getPluginName')
.addModifiers(Modifier.PUBLIC)
.returns(String.class)
.addStatement('return "$L"', header)
.build())

builder.addMethod(MethodSpec.methodBuilder('getName')
.addModifiers(Modifier.PUBLIC)
.returns(String.class)
.addStatement('return NAME')
.build())
builder.addMethod(MethodSpec.methodBuilder('getExtensionXName')
.addModifiers(Modifier.PUBLIC)
.returns(ParameterizedTypeName.get(Optional.class, String.class))
.addStatement('return $T.ofNullable($L)', Optional.class, "\"$extensionXName\"" ?: "null")
.build())

builder.addField(
FieldSpec.builder(byte.class, 'majorVersion', Modifier.PRIVATE)
.addAnnotation(Getter.class)
.initializer('$L', majorVersion)
builder.addMethod(MethodSpec.methodBuilder('getExtensionName')
.addModifiers(Modifier.PUBLIC)
.returns(ParameterizedTypeName.get(Optional.class, String.class))
.addStatement('return $T.ofNullable($L)', Optional.class, "\"$extensionName\"" ?: "null")
.build())

builder.addField(
FieldSpec.builder(byte.class, 'minorVersion', Modifier.PRIVATE)
.addAnnotation(Getter.class)
.initializer('$L', minorVersion)
.build())
builder.addMethod(MethodSpec.methodBuilder('getExtensionMultiword')
.addModifiers(Modifier.PUBLIC)
.returns(ParameterizedTypeName.get(Optional.class, Boolean.class))
.addStatement('return $T.ofNullable($L)', Optional.class, extensionMultiword ?: "null")
.build())

builder.addMethod(MethodSpec.methodBuilder('getMajorVersion')
.addModifiers(Modifier.PUBLIC)
.returns(ParameterizedTypeName.get(Optional.class, Byte.class))
.addStatement('return $T.ofNullable($L)', Optional.class, "(byte) $majorVersion" ?: "null")
.build())

builder.addMethod(MethodSpec.methodBuilder('getMinorVersion')
.addModifiers(Modifier.PUBLIC)
.returns(ParameterizedTypeName.get(Optional.class, Byte.class))
.addStatement('return $T.ofNullable($L)', Optional.class, "(byte) $minorVersion" ?: "null")
.build())

builder.addField(
FieldSpec.builder(byte.class, 'majorOpcode', Modifier.PRIVATE)
Expand All @@ -112,15 +115,35 @@ class XResult {
.addAnnotation(Override.class)
.returns(boolean.class)
.addParameter(ClassName.get(basePackage, 'XRequest'), 'request')
.addStatement("return request.getPluginName().equals(getPluginName())")

for(XTypeRequest request : requests.values()) {
supportedRequest.beginControlFlow('if(request instanceof $T)', request.javaType.className)
supportedRequest.addStatement('return true')
supportedRequest.endControlFlow()
builder.addMethod(supportedRequest.build())

MethodSpec.Builder supportedRequestCode = MethodSpec.methodBuilder('supportedRequest')
.addModifiers(Modifier.PUBLIC)
.addAnnotation(Override.class)
.returns(boolean.class)
.addParameter(byte.class, 'majorOpcode')
.addParameter(byte.class, 'minorOpcode')

if (header == 'xproto') {
for(XTypeRequest request : requests.values()) {
supportedRequestCode.beginControlFlow('if(majorOpcode == $L)', request.opCode)
supportedRequestCode.addStatement('return true')
supportedRequestCode.endControlFlow()
}
} else {
supportedRequestCode.addStatement("boolean isMajorOpcode = majorOpcode == getMajorOpcode()")
for(XTypeRequest request : requests.values()) {
supportedRequestCode.beginControlFlow('if(minorOpcode == $L)', request.opCode)
supportedRequestCode.addStatement('return isMajorOpcode')
supportedRequestCode.endControlFlow()
}
}
supportedRequest.addStatement('return false')

builder.addMethod(supportedRequest.build())
supportedRequestCode.addStatement('return false')

builder.addMethod(supportedRequestCode.build())

MethodSpec.Builder supportedEvent = MethodSpec.methodBuilder('supportedEvent')
.addModifiers(Modifier.PUBLIC)
Expand Down Expand Up @@ -154,6 +177,31 @@ class XResult {

builder.addMethod(supportedError.build())

MethodSpec.Builder readRequest = MethodSpec.methodBuilder('readRequest')
.addModifiers(Modifier.PUBLIC)
.addAnnotation(Override.class)
.returns(ClassName.get(basePackage, 'XRequest'))
.addParameter(byte.class, 'majorOpcode')
.addParameter(byte.class, 'minorOpcode')
.addParameter(ClassName.get(basePackage, 'X11Input'), 'in')
.addException(IOException.class)

for(XTypeRequest request : requests.values()) {

if (!extensionName) {
readRequest.beginControlFlow('if(majorOpcode == $T.OPCODE)', request.javaType.className)
readRequest.addStatement('return $T.read$L(in)', request.javaType.className, request.javaType.className.simpleName())
readRequest.endControlFlow()
} else {
readRequest.beginControlFlow('if(minorOpcode == $T.OPCODE)', request.javaType.className)
readRequest.addStatement('return $T.read$L(in)', request.javaType.className, request.javaType.className.simpleName())
readRequest.endControlFlow()
}
}
readRequest.addStatement('throw new $T("majorOpcode " + majorOpcode + ", minorOpcode " + minorOpcode + " is not supported")', IllegalArgumentException.class)

builder.addMethod(readRequest.build())

MethodSpec.Builder readEvent = MethodSpec.methodBuilder('readEvent')
.addModifiers(Modifier.PUBLIC)
.addAnnotation(Override.class)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,9 @@ class CaseTypeSpec extends XmlSpec {
typeSpec.toString() == '''\
@lombok.Value
@lombok.Builder
public class InputInfo implements com.github.moaxcp.x11client.protocol.XStruct, com.github.moaxcp.x11client.protocol.xproto.XprotoObject {
public class InputInfo implements com.github.moaxcp.x11client.protocol.XStruct {
public static final java.lang.String PLUGIN_NAME = "xproto";
private byte classId;
private byte len;
Expand All @@ -80,6 +82,10 @@ class CaseTypeSpec extends XmlSpec {
return 2;
}
public java.lang.String getPluginName() {
return PLUGIN_NAME;
}
public static class InputInfoBuilder {
public com.github.moaxcp.x11client.protocol.xproto.InputInfo.InputInfoBuilder classId(
com.github.moaxcp.x11client.protocol.xproto.InputClass classId) {
Expand Down Expand Up @@ -112,7 +118,9 @@ class CaseTypeSpec extends XmlSpec {
typeSpec.toString() == '''\
@lombok.Value
@lombok.Builder
public class InputInfoKey implements com.github.moaxcp.x11client.protocol.xproto.InputInfo, com.github.moaxcp.x11client.protocol.xproto.XprotoObject {
public class InputInfoKey implements com.github.moaxcp.x11client.protocol.xproto.InputInfo {
public static final java.lang.String PLUGIN_NAME = "xproto";
private byte classId;
private byte len;
Expand Down Expand Up @@ -154,6 +162,10 @@ class CaseTypeSpec extends XmlSpec {
return 8;
}
public java.lang.String getPluginName() {
return PLUGIN_NAME;
}
public static class InputInfoKeyBuilder {
public com.github.moaxcp.x11client.protocol.xproto.InputInfoKey.InputInfoKeyBuilder classId(
com.github.moaxcp.x11client.protocol.xproto.InputClass classId) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,9 @@ class JavaEnumPropertySpec extends XmlSpec {
typeSpec.toString() == '''\
@lombok.Value
@lombok.Builder
public class Struct implements com.github.moaxcp.x11client.protocol.XStruct, com.github.moaxcp.x11client.protocol.xproto.XprotoObject {
public class Struct implements com.github.moaxcp.x11client.protocol.XStruct {
public static final java.lang.String PLUGIN_NAME = "xproto";
private byte mask;
public static com.github.moaxcp.x11client.protocol.xproto.Struct readStruct(
Expand All @@ -52,6 +54,10 @@ class JavaEnumPropertySpec extends XmlSpec {
return 1;
}
public java.lang.String getPluginName() {
return PLUGIN_NAME;
}
public static class StructBuilder {
public com.github.moaxcp.x11client.protocol.xproto.Struct.StructBuilder mask(
com.github.moaxcp.x11client.protocol.xproto.EventMask mask) {
Expand Down
Loading

0 comments on commit 869173b

Please sign in to comment.