mirror of
https://github.com/rfc2822/GfxTablet
synced 2025-10-03 17:49:17 +02:00
Merge pull request #89 from akdor1154/tabletInputFix
Make networktablet act as a Tablet, not a Touchscreen
This commit is contained in:
commit
600469eb64
4 changed files with 68 additions and 8 deletions
|
@ -17,10 +17,17 @@ import at.bitfire.gfxtablet.NetEvent.Type;
|
|||
public class CanvasView extends View implements SharedPreferences.OnSharedPreferenceChangeListener {
|
||||
private static final String TAG = "GfxTablet.CanvasView";
|
||||
|
||||
private enum InRangeStatus {
|
||||
OutOfRange,
|
||||
InRange,
|
||||
FakeInRange
|
||||
}
|
||||
|
||||
final SharedPreferences settings;
|
||||
NetworkClient netClient;
|
||||
boolean acceptStylusOnly;
|
||||
int maxX, maxY;
|
||||
InRangeStatus inRangeStatus;
|
||||
|
||||
|
||||
// setup
|
||||
|
@ -35,6 +42,7 @@ public class CanvasView extends View implements SharedPreferences.OnSharedPrefer
|
|||
settings.registerOnSharedPreferenceChangeListener(this);
|
||||
setBackground();
|
||||
setInputMethods();
|
||||
inRangeStatus = InRangeStatus.OutOfRange;
|
||||
}
|
||||
|
||||
public void setNetworkClient(NetworkClient networkClient) {
|
||||
|
@ -83,13 +91,23 @@ public class CanvasView extends View implements SharedPreferences.OnSharedPrefer
|
|||
if (isEnabled()) {
|
||||
for (int ptr = 0; ptr < event.getPointerCount(); ptr++)
|
||||
if (!acceptStylusOnly || (event.getToolType(ptr) == MotionEvent.TOOL_TYPE_STYLUS)) {
|
||||
short nx = normalizeX(event.getX(ptr)),
|
||||
ny = normalizeY(event.getY(ptr)),
|
||||
npressure = normalizePressure(event.getPressure(ptr));
|
||||
Log.v(TAG, 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)
|
||||
netClient.getQueue().add(new NetEvent(Type.TYPE_MOTION,
|
||||
normalizeX(event.getX(ptr)),
|
||||
normalizeY(event.getY(ptr)),
|
||||
normalizePressure(event.getPressure(ptr))
|
||||
));
|
||||
switch (event.getActionMasked()) {
|
||||
case MotionEvent.ACTION_HOVER_MOVE:
|
||||
netClient.getQueue().add(new NetEvent(Type.TYPE_MOTION, nx, ny, npressure));
|
||||
break;
|
||||
case MotionEvent.ACTION_HOVER_ENTER:
|
||||
inRangeStatus = InRangeStatus.InRange;
|
||||
netClient.getQueue().add(new NetEvent(Type.TYPE_BUTTON, nx, ny, npressure, -1, true));
|
||||
break;
|
||||
case MotionEvent.ACTION_HOVER_EXIT:
|
||||
inRangeStatus = InRangeStatus.OutOfRange;
|
||||
netClient.getQueue().add(new NetEvent(Type.TYPE_BUTTON, nx, ny, npressure, -1, false));
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -110,11 +128,19 @@ public class CanvasView extends View implements SharedPreferences.OnSharedPrefer
|
|||
netClient.getQueue().add(new NetEvent(Type.TYPE_MOTION, nx, ny, npressure));
|
||||
break;
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
if (inRangeStatus == inRangeStatus.OutOfRange) {
|
||||
inRangeStatus = inRangeStatus.FakeInRange;
|
||||
netClient.getQueue().add(new NetEvent(Type.TYPE_BUTTON, nx, ny, (short)0, -1, true));
|
||||
}
|
||||
netClient.getQueue().add(new NetEvent(Type.TYPE_BUTTON, nx, ny, npressure, 0, true));
|
||||
break;
|
||||
case MotionEvent.ACTION_UP:
|
||||
case MotionEvent.ACTION_CANCEL:
|
||||
netClient.getQueue().add(new NetEvent(Type.TYPE_BUTTON, nx, ny, npressure, 0, false));
|
||||
if (inRangeStatus == inRangeStatus.FakeInRange) {
|
||||
inRangeStatus = inRangeStatus.OutOfRange;
|
||||
netClient.getQueue().add(new NetEvent(Type.TYPE_BUTTON, nx, ny, (short)0, -1, false));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -20,8 +20,21 @@ Packet structure, uses network byte order (big endian):
|
|||
1 unsigned int16 pressure (accepting full range 0..65535, but will clip to 32768 == pressure 1.0f on Android device)
|
||||
|
||||
when type == button event:
|
||||
1 signed int8 number of button, starting with 0
|
||||
1 signed int8 button id:
|
||||
-1: stylus in range pseudo-button
|
||||
0: left click / stylus in contact / button 0
|
||||
1: extra button 1
|
||||
2: extra button 2
|
||||
1 byte button status:
|
||||
0 button is released ("up")
|
||||
1 button is pressed ("down")
|
||||
|
||||
XInput will ignore BTN_TOUCH events if they are not preceeded by
|
||||
a BTN_TOOL_PEN event -- this would never happen for a real stylus,
|
||||
because it would imply the stylus is touching the pad, yet too far
|
||||
away from the pad to be detected.
|
||||
|
||||
A GfxTablet client must therefore be careful to send a "Button -1
|
||||
down" event before a "Button 0 down" event, to emulate this
|
||||
behaviour. If they are faking these events, they'll probably want
|
||||
to likewise send a "Button -1 up" event after a "Button 0 up" event.
|
||||
|
|
|
@ -35,6 +35,12 @@ void init_device(int fd)
|
|||
die("error: ioctl UI_SET_EVBIT EV_KEY");
|
||||
if (ioctl(fd, UI_SET_KEYBIT, BTN_TOUCH) < 0)
|
||||
die("error: ioctl UI_SET_KEYBIT");
|
||||
if (ioctl(fd, UI_SET_KEYBIT, BTN_TOOL_PEN) < 0)
|
||||
die("error: ioctl UI_SET_KEYBIT");
|
||||
if (ioctl(fd, UI_SET_KEYBIT, BTN_STYLUS) < 0)
|
||||
die("error: ioctl UI_SET_KEYBIT");
|
||||
if (ioctl(fd, UI_SET_KEYBIT, BTN_STYLUS2) < 0)
|
||||
die("error: ioctl UI_SET_KEYBIT");
|
||||
|
||||
// enable 2 main axes + pressure (absolute positioning)
|
||||
if (ioctl(fd, UI_SET_EVBIT, EV_ABS) < 0)
|
||||
|
@ -144,8 +150,19 @@ int main(void)
|
|||
send_event(device, EV_SYN, SYN_REPORT, 1);
|
||||
break;
|
||||
case EVENT_TYPE_BUTTON:
|
||||
// stylus hovering
|
||||
if (ev_pkt.button == -1)
|
||||
send_event(device, EV_KEY, BTN_TOOL_PEN, ev_pkt.down);
|
||||
// stylus touching
|
||||
if (ev_pkt.button == 0)
|
||||
send_event(device, EV_KEY, BTN_TOUCH, ev_pkt.down);
|
||||
// button 1
|
||||
if (ev_pkt.button == 1)
|
||||
send_event(device, EV_KEY, BTN_STYLUS, ev_pkt.down);
|
||||
// button 2
|
||||
if (ev_pkt.button == 2)
|
||||
send_event(device, EV_KEY, BTN_STYLUS2, ev_pkt.down);
|
||||
printf("sent button: %hhi, %hhu\n", ev_pkt.button, ev_pkt.down);
|
||||
send_event(device, EV_SYN, SYN_REPORT, 1);
|
||||
break;
|
||||
|
||||
|
|
|
@ -20,7 +20,11 @@ struct event_packet
|
|||
};
|
||||
|
||||
struct { /* only required for EVENT_TYPE_BUTTON */
|
||||
int8_t button; /* number of button, beginning with 1 */
|
||||
int8_t button; /* button id:
|
||||
-1 = stylus in range,
|
||||
0 = tap/left click/button 0,
|
||||
1 = button 1,
|
||||
2 = button 2 */
|
||||
int8_t down; /* 1 = button down, 0 = button up */
|
||||
};
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue