1
0
Fork 0
mirror of https://github.com/rfc2822/GfxTablet synced 2025-10-03 09:39:16 +02:00

* app refactoring

* uinput driver
This commit is contained in:
Richard Hirner 2013-01-26 21:24:36 +01:00
parent 1b93a87ed0
commit cef17da6d2
34 changed files with 251 additions and 103 deletions

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.gimpusers.xorgtablet" package="at.bitfire.gfxtablet"
android:versionCode="1" android:versionCode="1"
android:versionName="1.0" > android:versionName="1.0" >
@ -15,7 +15,7 @@
android:icon="@drawable/ic_launcher" android:icon="@drawable/ic_launcher"
android:label="@string/app_name" > android:label="@string/app_name" >
<activity <activity
android:name="com.gimpusers.xorgtablet.CanvasActivity" android:name="at.bitfire.gfxtablet.CanvasActivity"
android:label="@string/app_name" android:label="@string/app_name"
android:screenOrientation="landscape" > android:screenOrientation="landscape" >
<intent-filter> <intent-filter>
@ -25,11 +25,11 @@
</intent-filter> </intent-filter>
</activity> </activity>
<activity <activity
android:name="com.gimpusers.xorgtablet.SettingsActivity" android:name="at.bitfire.gfxtablet.SettingsActivity"
android:label="@string/title_activity_settings" > android:label="@string/title_activity_settings" >
<meta-data <meta-data
android:name="android.support.PARENT_ACTIVITY" android:name="android.support.PARENT_ACTIVITY"
android:value="com.gimpusers.xorgtablet.CanvasActivity" /> android:value="at.bitfire.gfxtablet.CanvasActivity" />
</activity> </activity>
</application> </application>

View file

Before

Width:  |  Height:  |  Size: 8.2 KiB

After

Width:  |  Height:  |  Size: 8.2 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 4.5 KiB

After

Width:  |  Height:  |  Size: 4.5 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Before After
Before After

View file

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">GfxTablet</string>
<string name="menu_settings">Settings</string>
<string name="preferences_host_title">Network host</string>
<string name="stylus_preference">Sense stylus only</string>
<string name="menu_about">About / Help</string>
</resources>

View file

@ -0,0 +1,9 @@
<preference-headers
xmlns:android="http://schemas.android.com/apk/res/android">
<header android:fragment="at.bitfire.gfxtablet.SettingsActivity$NetworkPrefsFragment"
android:title="Networking" />
<header android:fragment="at.bitfire.gfxtablet.SettingsActivity$DrawingPrefsFragment"
android:title="Drawing" />
</preference-headers>

View file

@ -1,4 +1,6 @@
package com.gimpusers.xorgtablet; package at.bitfire.gfxtablet;
import at.bitfire.gfxtablet.R;
import android.net.Uri; import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
@ -6,16 +8,14 @@ import android.preference.PreferenceManager;
import android.app.Activity; import android.app.Activity;
import android.content.Intent; import android.content.Intent;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.view.Menu; import android.view.Menu;
import android.view.MenuItem; import android.view.MenuItem;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import android.widget.Toast;
public class CanvasActivity extends Activity { public class CanvasActivity extends Activity {
CanvasView canvas; CanvasView canvas;
SharedPreferences prefs; SharedPreferences prefs;
XorgClient xorgClient; NetworkClient netClient;
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
@ -27,15 +27,15 @@ public class CanvasActivity extends Activity {
setContentView(R.layout.activity_canvas); setContentView(R.layout.activity_canvas);
LinearLayout layout = (LinearLayout)findViewById(R.id.canvas_layout); LinearLayout layout = (LinearLayout)findViewById(R.id.canvas_layout);
new Thread(xorgClient = new XorgClient(PreferenceManager.getDefaultSharedPreferences(this))).start(); new Thread(netClient = new NetworkClient(PreferenceManager.getDefaultSharedPreferences(this))).start();
canvas = new CanvasView(this, xorgClient); canvas = new CanvasView(this, netClient);
layout.addView(canvas); layout.addView(canvas);
} }
@Override @Override
protected void onDestroy() { protected void onDestroy() {
xorgClient.getQueue().add(new XDisconnectEvent()); netClient.getQueue().add(new NetDisconnectEvent());
super.onDestroy(); super.onDestroy();
} }
@ -46,7 +46,7 @@ public class CanvasActivity extends Activity {
} }
public void showAbout(MenuItem item) { public void showAbout(MenuItem item) {
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(("https://github.com/rfc2822/XorgTablet")))); startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(("http://rfc2822.github.com/GfxTablet"))));
} }
public void showSettings(MenuItem item) { public void showSettings(MenuItem item) {

View file

@ -1,6 +1,4 @@
package com.gimpusers.xorgtablet; package at.bitfire.gfxtablet;
import java.util.concurrent.ExecutionException;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.content.Context; import android.content.Context;
@ -8,7 +6,6 @@ import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener; import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.preference.PreferenceManager; import android.preference.PreferenceManager;
import android.util.Log;
import android.view.MotionEvent; import android.view.MotionEvent;
import android.view.View; import android.view.View;
import android.widget.Toast; import android.widget.Toast;
@ -17,11 +14,11 @@ import android.widget.Toast;
public class CanvasView extends View implements OnSharedPreferenceChangeListener { public class CanvasView extends View implements OnSharedPreferenceChangeListener {
final static int PRESSURE_RESOLUTION = 10000; final static int PRESSURE_RESOLUTION = 10000;
XorgClient xorgClient; NetworkClient netClient;
SharedPreferences settings; SharedPreferences settings;
boolean acceptStylusOnly; boolean acceptStylusOnly;
public CanvasView(Context context, XorgClient xorgClient) { public CanvasView(Context context, NetworkClient netClient) {
super(context); super(context);
// disable until networking has been configured // disable until networking has been configured
@ -32,7 +29,7 @@ public class CanvasView extends View implements OnSharedPreferenceChangeListener
settings.registerOnSharedPreferenceChangeListener(this); settings.registerOnSharedPreferenceChangeListener(this);
reconfigureAcceptedInputDevices(); reconfigureAcceptedInputDevices();
this.xorgClient = xorgClient; this.netClient = netClient;
new ConfigureNetworkingTask().execute(); new ConfigureNetworkingTask().execute();
} }
@ -51,7 +48,7 @@ public class CanvasView extends View implements OnSharedPreferenceChangeListener
@Override @Override
protected void onSizeChanged (int w, int h, int oldw, int oldh) { protected void onSizeChanged (int w, int h, int oldw, int oldh) {
Toast.makeText(getContext(), String.format("%dx%d", w, h), Toast.LENGTH_SHORT).show(); Toast.makeText(getContext(), String.format("%dx%d", w, h), Toast.LENGTH_SHORT).show();
xorgClient.getQueue().add(new XConfigurationEvent(w, h, PRESSURE_RESOLUTION)); netClient.getQueue().add(new NetConfigurationEvent(w, h, PRESSURE_RESOLUTION));
} }
@ -62,7 +59,7 @@ public class CanvasView extends View implements OnSharedPreferenceChangeListener
if (!acceptStylusOnly || (event.getToolType(ptr) == MotionEvent.TOOL_TYPE_STYLUS)) { if (!acceptStylusOnly || (event.getToolType(ptr) == MotionEvent.TOOL_TYPE_STYLUS)) {
//Log.i("XorgTablet", String.format("Generic motion event logged: %f|%f, pressure %f", event.getX(ptr), event.getY(ptr), event.getPressure(ptr))); //Log.i("XorgTablet", String.format("Generic motion event logged: %f|%f, pressure %f", event.getX(ptr), event.getY(ptr), event.getPressure(ptr)));
if (event.getActionMasked() == MotionEvent.ACTION_HOVER_MOVE) if (event.getActionMasked() == MotionEvent.ACTION_HOVER_MOVE)
xorgClient.getQueue().add(new XMotionEvent((int)event.getX(ptr), (int)event.getY(ptr), (int)(event.getPressure(ptr)*PRESSURE_RESOLUTION))); netClient.getQueue().add(new NetMotionEvent((int)event.getX(ptr), (int)event.getY(ptr), (int)(event.getPressure(ptr)*PRESSURE_RESOLUTION)));
} }
return true; return true;
} }
@ -77,14 +74,14 @@ public class CanvasView extends View implements OnSharedPreferenceChangeListener
//Log.i("XorgTablet", String.format("Touch event logged: %f|%f, pressure %f", event.getX(ptr), event.getY(ptr), event.getPressure(ptr))); //Log.i("XorgTablet", String.format("Touch event logged: %f|%f, pressure %f", event.getX(ptr), event.getY(ptr), event.getPressure(ptr)));
switch (event.getActionMasked()) { switch (event.getActionMasked()) {
case MotionEvent.ACTION_MOVE: case MotionEvent.ACTION_MOVE:
xorgClient.getQueue().add(new XMotionEvent((int)event.getX(ptr), (int)event.getY(ptr), (int)(event.getPressure(ptr)*PRESSURE_RESOLUTION))); netClient.getQueue().add(new NetMotionEvent((int)event.getX(ptr), (int)event.getY(ptr), (int)(event.getPressure(ptr)*PRESSURE_RESOLUTION)));
break; break;
case MotionEvent.ACTION_DOWN: case MotionEvent.ACTION_DOWN:
xorgClient.getQueue().add(new XButtonEvent((int)event.getX(ptr), (int)event.getY(ptr), (int)(event.getPressure(ptr)*PRESSURE_RESOLUTION), true)); netClient.getQueue().add(new NetButtonEvent((int)event.getX(ptr), (int)event.getY(ptr), (int)(event.getPressure(ptr)*PRESSURE_RESOLUTION), true));
break; break;
case MotionEvent.ACTION_UP: case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL: case MotionEvent.ACTION_CANCEL:
xorgClient.getQueue().add(new XButtonEvent((int)event.getX(ptr), (int)event.getY(ptr), (int)(event.getPressure(ptr)*PRESSURE_RESOLUTION), false)); netClient.getQueue().add(new NetButtonEvent((int)event.getX(ptr), (int)event.getY(ptr), (int)(event.getPressure(ptr)*PRESSURE_RESOLUTION), false));
break; break;
} }
@ -98,7 +95,7 @@ public class CanvasView extends View implements OnSharedPreferenceChangeListener
private class ConfigureNetworkingTask extends AsyncTask<Void, Void, Boolean> { private class ConfigureNetworkingTask extends AsyncTask<Void, Void, Boolean> {
@Override @Override
protected Boolean doInBackground(Void... params) { protected Boolean doInBackground(Void... params) {
return xorgClient.configureNetworking(); return netClient.configureNetworking();
} }
protected void onPostExecute(Boolean success) { protected void onPostExecute(Boolean success) {

View file

@ -1,13 +1,13 @@
package com.gimpusers.xorgtablet; package at.bitfire.gfxtablet;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream; import java.io.DataOutputStream;
import java.io.IOException; import java.io.IOException;
public class XButtonEvent extends XEvent { public class NetButtonEvent extends NetEvent {
boolean down; boolean down;
public XButtonEvent(int x, int y, int pressure, boolean down) { public NetButtonEvent(int x, int y, int pressure, boolean down) {
super(x, y, pressure); super(x, y, pressure);
this.down = down; this.down = down;
} }

View file

@ -1,11 +1,11 @@
package com.gimpusers.xorgtablet; package at.bitfire.gfxtablet;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream; import java.io.DataOutputStream;
import java.io.IOException; import java.io.IOException;
public class XConfigurationEvent extends XEvent { public class NetConfigurationEvent extends NetEvent {
public XConfigurationEvent(int x, int y, int pressure) { public NetConfigurationEvent(int x, int y, int pressure) {
super(x, y, pressure); super(x, y, pressure);
} }

View file

@ -0,0 +1,12 @@
package at.bitfire.gfxtablet;
public class NetDisconnectEvent extends NetEvent {
public NetDisconnectEvent() {
super(0, 0, 0);
}
@Override
public byte[] toByteArray() {
return null;
}
}

View file

@ -1,13 +1,13 @@
package com.gimpusers.xorgtablet; package at.bitfire.gfxtablet;
public abstract class XEvent { public abstract class NetEvent {
int x, y, pressure; int x, y, pressure;
public int getX() { return x; } public int getX() { return x; }
public int getY() { return y; } public int getY() { return y; }
public int getPressure() { return pressure; } public int getPressure() { return pressure; }
public XEvent(int x, int y, int pressure) { public NetEvent(int x, int y, int pressure) {
this.x = Math.max(x, 0); this.x = Math.max(x, 0);
this.y = Math.max(y, 0); this.y = Math.max(y, 0);
this.pressure = pressure; this.pressure = pressure;

View file

@ -1,11 +1,11 @@
package com.gimpusers.xorgtablet; package at.bitfire.gfxtablet;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream; import java.io.DataOutputStream;
import java.io.IOException; import java.io.IOException;
public class XMotionEvent extends XEvent { public class NetMotionEvent extends NetEvent {
public XMotionEvent(int x, int y, int pressure) { public NetMotionEvent(int x, int y, int pressure) {
super(x, y, pressure); super(x, y, pressure);
} }

View file

@ -1,7 +1,5 @@
package com.gimpusers.xorgtablet; package at.bitfire.gfxtablet;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.net.DatagramPacket; import java.net.DatagramPacket;
import java.net.DatagramSocket; import java.net.DatagramSocket;
import java.net.InetAddress; import java.net.InetAddress;
@ -11,18 +9,18 @@ import java.util.concurrent.LinkedBlockingQueue;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.util.Log; import android.util.Log;
// see xf86-networktablet on Github for details about the protocol // see "drivers" directory in Github repository for details about the protocol
public class XorgClient implements Runnable { public class NetworkClient implements Runnable {
LinkedBlockingQueue<XEvent> motionQueue = new LinkedBlockingQueue<XEvent>(); LinkedBlockingQueue<NetEvent> motionQueue = new LinkedBlockingQueue<NetEvent>();
LinkedBlockingQueue<XEvent> getQueue() { return motionQueue; } LinkedBlockingQueue<NetEvent> getQueue() { return motionQueue; }
InetAddress destAddress; InetAddress destAddress;
SharedPreferences preferences; SharedPreferences preferences;
XConfigurationEvent lastConfiguration = null; NetConfigurationEvent lastConfiguration = null;
XorgClient(SharedPreferences preferences) { NetworkClient(SharedPreferences preferences) {
this.preferences = preferences; this.preferences = preferences;
} }
@ -46,17 +44,14 @@ public class XorgClient implements Runnable {
try { try {
DatagramSocket socket = new DatagramSocket(); DatagramSocket socket = new DatagramSocket();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(baos);
while (true) { while (true) {
XEvent event = motionQueue.take(); NetEvent event = motionQueue.take();
// save resolution, even if not sending it // save resolution, even if not sending it
if (event.getClass() == XConfigurationEvent.class) if (event.getClass() == NetConfigurationEvent.class)
lastConfiguration = (XConfigurationEvent)event; lastConfiguration = (NetConfigurationEvent)event;
// graceful shutdown // graceful shutdown
else if (event.getClass() == XDisconnectEvent.class) else if (event.getClass() == NetDisconnectEvent.class)
break; break;
if (destAddress == null) // no valid destination host if (destAddress == null) // no valid destination host
@ -65,11 +60,9 @@ public class XorgClient implements Runnable {
byte[] data = event.toByteArray(); byte[] data = event.toByteArray();
DatagramPacket pkt = new DatagramPacket(data, data.length, destAddress, 40117); DatagramPacket pkt = new DatagramPacket(data, data.length, destAddress, 40117);
socket.send(pkt); socket.send(pkt);
baos.reset();
} }
} catch (Exception e) { } catch (Exception e) {
Log.e("XorgTablet", "motionQueue failed: " + e.getMessage()); Log.e("GfxTablet", "motionQueue failed: " + e.getMessage());
} }
} }
} }

View file

@ -1,26 +1,14 @@
package com.gimpusers.xorgtablet; package at.bitfire.gfxtablet;
import android.annotation.TargetApi;
import android.content.Context;
import android.content.res.Configuration;
import android.media.Ringtone;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.preference.ListPreference;
import android.preference.Preference;
import android.preference.PreferenceActivity; import android.preference.PreferenceActivity;
import android.preference.PreferenceCategory;
import android.preference.PreferenceFragment; import android.preference.PreferenceFragment;
import android.preference.PreferenceManager;
import android.preference.RingtonePreference;
import android.text.TextUtils;
import android.view.MenuItem; import android.view.MenuItem;
import android.support.v4.app.NavUtils;
import java.util.List; import java.util.List;
import at.bitfire.gfxtablet.R;
public class SettingsActivity extends PreferenceActivity { public class SettingsActivity extends PreferenceActivity {
public static final String public static final String
KEY_PREF_HOST = "host_preference", KEY_PREF_HOST = "host_preference",

1
driver-uinput/.gitignore vendored Normal file
View file

@ -0,0 +1 @@
networktablet

2
driver-uinput/Makefile Normal file
View file

@ -0,0 +1,2 @@
networktablet : networktablet.c

View file

@ -0,0 +1,142 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <limits.h>
#include <arpa/inet.h>
#include <linux/input.h>
#include <linux/uinput.h>
#include "protocol.h"
#define die(str, args...) { \
perror(str); \
exit(EXIT_FAILURE); \
}
void init_device(int fd)
{
struct uinput_user_dev uidev;
// 1 button
if (ioctl(fd, UI_SET_EVBIT, EV_KEY) < 0)
die("error: ioctl UI_SET_EVBIT EV_KEY");
if (ioctl(fd, UI_SET_KEYBIT, BTN_TOUCH) < 0)
die("error: ioctl UI_SET_KEYBIT");
// 2 main axes + pressure (absolute positioning)
if (ioctl(fd, UI_SET_EVBIT, EV_ABS) < 0)
die("error: ioctl UI_SET_EVBIT EV_ABS");
if (ioctl(fd, UI_SET_ABSBIT, ABS_X) < 0)
die("error: ioctl UI_SETEVBIT ABS_X");
if (ioctl(fd, UI_SET_ABSBIT, ABS_Y) < 0)
die("error: ioctl UI_SETEVBIT ABS_Y");
if (ioctl(fd, UI_SET_ABSBIT, ABS_PRESSURE) < 0)
die("error: ioctl UI_SETEVBIT ABS_PRESSURE");
memset(&uidev, 0, sizeof(uidev));
snprintf(uidev.name, UINPUT_MAX_NAME_SIZE, "Network Tablet");
uidev.id.bustype = BUS_VIRTUAL;
uidev.id.vendor = 0x1;
uidev.id.product = 0x1;
uidev.id.version = 1;
uidev.absmin[ABS_X] = 0;
uidev.absmax[ABS_X] = INT_MAX;
uidev.absmin[ABS_Y] = 0;
uidev.absmax[ABS_Y] = INT_MAX;
uidev.absmin[ABS_PRESSURE] = 0;
uidev.absmax[ABS_PRESSURE] = 10000; // 10,000 instead of 32,767 because sometimes there is pressure >1.0
if (write(fd, &uidev, sizeof(uidev)) < 0)
die("error: write");
if (ioctl(fd, UI_DEV_CREATE) < 0)
die("error: ioctl");
}
int prepare_socket()
{
int s;
struct sockaddr_in addr;
if ((s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
die("error: prepare_socket()");
bzero(&addr, sizeof(struct sockaddr_in));
addr.sin_family = AF_INET;
addr.sin_port = htons(NETWORKTABLET_PORT);
addr.sin_addr.s_addr = htonl(INADDR_ANY);
if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) == -1)
die("error: prepare_socket()");
return s;
}
void send_event(int device, int type, int code, int value)
{
struct input_event ev;
ev.type = type;
ev.code = code;
ev.value = value;
if (write(device, &ev, sizeof(ev)) < 0)
error("error: write()");
}
int main(void)
{
int device, socket;
struct event_packet ev_pkt;
int x, y, btn_down = 0;
int max_x = INT_MAX, max_y = INT_MAX;
if ((device = open("/dev/uinput", O_WRONLY | O_NONBLOCK)) < 0)
die("error: open");
init_device(device);
socket = prepare_socket();
while (recv(socket, &ev_pkt, sizeof(ev_pkt), 0) >= 7) { // every packet has at least 7 bytes
printf("."); fflush(0);
ev_pkt.x = ntohs(ev_pkt.x);
ev_pkt.y = ntohs(ev_pkt.y);
ev_pkt.pressure = ntohs(ev_pkt.pressure);
//printf("x: %hi, y: %hi, pressure: %hi\n", ev_pkt.x, ev_pkt.y, ev_pkt.pressure);
x = (long)ev_pkt.x * INT_MAX/max_x;
y = (long)ev_pkt.y * INT_MAX/max_y;
send_event(device, EV_ABS, ABS_X, x);
send_event(device, EV_ABS, ABS_Y, y);
send_event(device, EV_ABS, ABS_PRESSURE, ev_pkt.pressure);
switch (ev_pkt.type) {
case EVENT_TYPE_SET_RESOLUTION: {
struct input_absinfo absinfo;
max_x = ev_pkt.x;
max_y = ev_pkt.y;
printf("Set resolution to %hix%hi\n", max_x+1, max_y+1);
break;
}
case EVENT_TYPE_MOTION:
send_event(device, EV_SYN, SYN_REPORT, 1);
break;
case EVENT_TYPE_BUTTON:
if (ev_pkt.button == 1)
send_event(device, EV_KEY, BTN_TOUCH, ev_pkt.down);
send_event(device, EV_SYN, SYN_REPORT, 1);
break;
}
}
close(socket);
ioctl(device, UI_DEV_DESTROY);
close(device);
return 0;
}

26
driver-uinput/protocol.h Normal file
View file

@ -0,0 +1,26 @@
#define NETWORKTABLET_PORT 40117
#pragma pack(push)
#pragma pack(1)
#define EVENT_TYPE_MOTION 0
#define EVENT_TYPE_BUTTON 1
#define EVENT_TYPE_SET_RESOLUTION 2
struct event_packet
{
char type; /* EVENT_TYPE_... */
struct { /* required */
short x, y;
short pressure;
};
struct { /* only required for EVENT_TYPE_BUTTON */
char button; /* number of button, beginning with 1 */
char down; /* 1 = button down, 0 = button up */
};
};
#pragma pack(pop)

View file

@ -1,10 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">XorgTablet</string>
<string name="menu_settings">Settings</string>
<string name="preferences_host_title">X.org host</string>
<string name="stylus_preference">Sense stylus only</string>
<string name="menu_about">About</string>
</resources>

View file

@ -1,10 +0,0 @@
<preference-headers
xmlns:android="http://schemas.android.com/apk/res/android">
<header android:fragment="com.gimpusers.xorgtablet.SettingsActivity$NetworkPrefsFragment"
android:title="Networking" />
<header android:fragment="com.gimpusers.xorgtablet.SettingsActivity$DrawingPrefsFragment"
android:title="Drawing" />
</preference-headers>

View file

@ -1,12 +0,0 @@
package com.gimpusers.xorgtablet;
public class XDisconnectEvent extends XEvent {
public XDisconnectEvent() {
super(0, 0, 0);
}
@Override
public byte[] toByteArray() {
return null;
}
}