Skip to content

Commit

Permalink
Adding AtomService for creating and caching new atoms.
Browse files Browse the repository at this point in the history
  • Loading branch information
moaxcp committed Dec 27, 2020
1 parent 97a01af commit 01cfbf4
Show file tree
Hide file tree
Showing 10 changed files with 273 additions and 132 deletions.
22 changes: 18 additions & 4 deletions .github/workflows/gradle.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,30 @@ jobs:
- uses: actions/checkout@v2
with:
fetch-depth: 0
- name: Set up JDK 1.8
- name: Set up JDK 11
uses: actions/setup-java@v1
with:
java-version: 1.11
java-version: 11
- name: Cache SonarCloud packages
uses: actions/cache@v1
with:
path: ~/.sonar/cache
key: ${{ runner.os }}-sonar
restore-keys: ${{ runner.os }}-sonar
- name: Cache Gradle packages
uses: actions/cache@v1
with:
path: ~/.gradle/caches
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle') }}
restore-keys: ${{ runner.os }}-gradle
- name: Grant execute permission for gradlew
run: chmod +x gradlew
- name: Build with Gradle
run: ./gradlew build
- name: Jacoco Test Report
run: ./gradlew jacocoTestReport
- name: Sonar scan
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SONAR_LOGIN: ${{ secrets.SONAR_LOGIN }}
run: ./gradlew sonarqube
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
run: ./gradlew sonarqube --info
238 changes: 118 additions & 120 deletions README.md

Large diffs are not rendered by default.

4 changes: 1 addition & 3 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -141,10 +141,8 @@ signing {

sonarqube {
properties {
property "sonar.projectKey", "com.github.moaxcp.x11:x11-client"
property 'sonar.host.url', 'https://sonarcloud.io'
property 'sonar.organization', 'moaxcp'
if(System.getenv('sonar_login')) {
property 'sonar.login', System.getenv('SONAR_LOGIN')
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ void clientTestXFunctions() throws IOException {
try(X11Client client = X11Client.connect()) {
int wid = client.createSimpleWindow((short) 10, (short) 10, (short) 600, (short) 480, EventMask.EXPOSURE, EventMask.KEY_PRESS);
client.storeName(wid, "Hello World!");
int deleteAtom = client.internAtom("WM_DELETE_WINDOW");
int deleteAtom = client.getAtom("WM_DELETE_WINDOW");
client.setWMProtocols(wid, deleteAtom);
client.mapWindow(wid);
int gc = client.createGC(0, wid);
Expand Down
45 changes: 45 additions & 0 deletions src/main/java/com/github/moaxcp/x11client/AtomService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package com.github.moaxcp.x11client;

import com.github.moaxcp.x11client.protocol.AtomValue;
import com.github.moaxcp.x11client.protocol.xproto.Atom;
import com.github.moaxcp.x11client.protocol.xproto.InternAtom;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

import static com.github.moaxcp.x11client.protocol.Utilities.stringToByteList;

public class AtomService {
private final XProtocolService protocolService;
private Map<Integer,AtomValue> atomIds = new HashMap<>();
private Map<String, AtomValue> atomNames = new HashMap<>();
public AtomService(XProtocolService protocolService) {
this.protocolService = protocolService;
for(Atom atom : Atom.values()) {
add(new AtomValue(atom.getValue(), atom.toString()));
}
}

private void add(AtomValue atom) {
atomIds.put(atom.getId(), atom);
atomNames.put(atom.getName(), atom);
}

public AtomValue getAtom(Atom atom) {
return atomIds.get(atom.getValue());
}

public Optional<AtomValue> getAtom(int id) {
return Optional.ofNullable(atomIds.get(id));
}

public AtomValue getAtom(String name) {
if(atomNames.containsKey(name)) {
return atomNames.get(name);
}
int id = protocolService.send(InternAtom.builder().name(stringToByteList(name)).nameLen((short) name.length()).build()).getAtom();
AtomValue result = new AtomValue(id, name);
add(result);
return result;
}
}
13 changes: 10 additions & 3 deletions src/main/java/com/github/moaxcp/x11client/X11Client.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ public class X11Client implements AutoCloseable {
private final X11Connection connection;
private final XProtocolService protocolService;
private final ResourceIdService resourceIdService;
private final AtomService atomService;

/**
* Creates a client for the given displayName and authority.
Expand Down Expand Up @@ -53,6 +54,7 @@ private X11Client(X11Connection connection) {
this.connection = connection;
protocolService = new XProtocolService(connection.getSetup(), connection.getX11Input(), connection.getX11Output());
resourceIdService = new ResourceIdService(protocolService, connection.getSetup().getResourceIdMask(), connection.getSetup().getResourceIdBase());
atomService = new AtomService(protocolService);
}

public boolean loadedPlugin(String name) {
Expand Down Expand Up @@ -161,8 +163,13 @@ public int nextResourceId() {
return resourceIdService.nextResourceId();
}

public int internAtom(String name) {
return send(InternAtom.builder().name(stringToByteList(name)).nameLen((short) name.length()).build()).getAtom();
/**
* Returns the id of the named Atom. If the atom does not exist on the x11 server an InternAtom request is made.
* @param name
* @return
*/
public int getAtom(String name) {
return atomService.getAtom(name).getId();
}

//XRaiseWindow https://github.com/mirror/libX11/blob/caa71668af7fd3ebdd56353c8f0ab90824773969/src/RaiseWin.c
Expand All @@ -185,7 +192,7 @@ public void storeName(int wid, String name) {
}

public void setWMProtocols(int wid, int atom) {
int wmProtocols = internAtom("WM_PROTOCOLS");
int wmProtocols = getAtom("WM_PROTOCOLS");
send(ChangeProperty.builder()
.window(wid)
.property(wmProtocols)
Expand Down
14 changes: 14 additions & 0 deletions src/main/java/com/github/moaxcp/x11client/protocol/AtomValue.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.github.moaxcp.x11client.protocol;

import lombok.NonNull;
import lombok.Value;

/**
* An atom. May be a predefined atom or an intern atom.
*/
@Value
public class AtomValue {
int id;
@NonNull
String name;
}
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ public static Family getByCode(int code) {
* @param protocolName
* @param protocolData
* @throws NullPointerException if any parameter is null.
* @throws IllegalArgumentException if displayNumber is < 0 or protocolName is empty.
* @throws IllegalArgumentException if displayNumber is less than 0 or protocolName is empty.
*/
public XAuthority(@NonNull Family family, @NonNull List<Byte> address, int displayNumber, @NonNull List<Byte> protocolName, @NonNull List<Byte> protocolData) {
this.family = family;
Expand Down
51 changes: 51 additions & 0 deletions src/test/java/com/github/moaxcp/x11client/AtomServiceTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package com.github.moaxcp.x11client;

import com.github.moaxcp.x11client.protocol.AtomValue;
import com.github.moaxcp.x11client.protocol.xproto.Atom;
import com.github.moaxcp.x11client.protocol.xproto.InternAtom;
import com.github.moaxcp.x11client.protocol.xproto.InternAtomReply;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.BDDMockito.given;
import static org.mockito.BDDMockito.then;

@ExtendWith(MockitoExtension.class)
public class AtomServiceTest {
@Mock
private XProtocolService protocolService;
private AtomService service;

@BeforeEach
void setup() {
service = new AtomService(protocolService);
}

@Test
void getAtomId_has_predefined_atoms() {
AtomValue atom = service.getAtom(Atom.BITMAP);
assertThat(atom.getId()).isEqualTo(Atom.BITMAP.getValue());
assertThat(atom.getName()).isEqualTo("BITMAP");
}

@Test
void getAtomName_has_predefined_atoms() {
AtomValue atom = service.getAtom("BITMAP");
assertThat(atom.getId()).isEqualTo(Atom.BITMAP.getValue());
assertThat(atom.getName()).isEqualTo("BITMAP");
}

@Test
void getAtomName_creates_new_atoms() {
given(protocolService.send(any(InternAtom.class))).willReturn(InternAtomReply.builder().atom(100).build());
AtomValue atom = service.getAtom("DELETE_WINDOW");
assertThat(atom.getId()).isEqualTo(100);
assertThat(atom.getName()).isEqualTo("DELETE_WINDOW");
then(protocolService).should().send(any(InternAtom.class));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.github.moaxcp.x11client.protocol;

import org.junit.jupiter.api.Test;

import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertThrows;

public class AtomValueTest {
@Test
void null_name_fails() {
NullPointerException exception = assertThrows(NullPointerException.class, () -> new AtomValue(1, null));
assertThat(exception).hasMessage("name is marked non-null but is null");
}
}

0 comments on commit 01cfbf4

Please sign in to comment.