mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge
synced 2024-11-25 11:26:47 +01:00
Pebble: Support taking Pebble Time screenshots. Closes #97.
This commit is contained in:
parent
12337836bc
commit
1150ad2b8d
@ -202,6 +202,97 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
||||
GBDeviceEventScreenshot mDevEventScreenshot = null;
|
||||
int mScreenshotRemaining = -1;
|
||||
|
||||
//monochrome black + white
|
||||
static final byte[] clut_pebble = {
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
(byte) 0xff, (byte) 0xff, (byte) 0xff, 0x00
|
||||
};
|
||||
|
||||
// linear BGR222 (6 bit, 64 entries)
|
||||
static final byte[] clut_pebbletime = new byte[]{
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x55, 0x00, 0x00, 0x00,
|
||||
(byte) 0xaa, 0x00, 0x00, 0x00,
|
||||
(byte) 0xff, 0x00, 0x00, 0x00,
|
||||
|
||||
0x00, 0x55, 0x00, 0x00,
|
||||
0x55, 0x55, 0x00, 0x00,
|
||||
(byte) 0xaa, 0x55, 0x00, 0x00,
|
||||
(byte) 0xff, 0x55, 0x00, 0x00,
|
||||
|
||||
0x00, (byte) 0xaa, 0x00, 0x00,
|
||||
0x55, (byte) 0xaa, 0x00, 0x00,
|
||||
(byte) 0xaa, (byte) 0xaa, 0x00, 0x00,
|
||||
(byte) 0xff, (byte) 0xaa, 0x00, 0x00,
|
||||
|
||||
0x00, (byte) 0xff, 0x00, 0x00,
|
||||
0x55, (byte) 0xff, 0x00, 0x00,
|
||||
(byte) 0xaa, (byte) 0xff, 0x00, 0x00,
|
||||
(byte) 0xff, (byte) 0xff, 0x00, 0x00,
|
||||
|
||||
0x00, 0x00, 0x55, 0x00,
|
||||
0x55, 0x00, 0x55, 0x00,
|
||||
(byte) 0xaa, 0x00, 0x55, 0x00,
|
||||
(byte) 0xff, 0x00, 0x55, 0x00,
|
||||
|
||||
0x00, 0x55, 0x55, 0x00,
|
||||
0x55, 0x55, 0x55, 0x00,
|
||||
(byte) 0xaa, 0x55, 0x55, 0x00,
|
||||
(byte) 0xff, 0x55, 0x55, 0x00,
|
||||
|
||||
0x00, (byte) 0xaa, 0x55, 0x00,
|
||||
0x55, (byte) 0xaa, 0x55, 0x00,
|
||||
(byte) 0xaa, (byte) 0xaa, 0x55, 0x00,
|
||||
(byte) 0xff, (byte) 0xaa, 0x55, 0x00,
|
||||
|
||||
0x00, (byte) 0xff, 0x55, 0x00,
|
||||
0x55, (byte) 0xff, 0x55, 0x00,
|
||||
(byte) 0xaa, (byte) 0xff, 0x55, 0x00,
|
||||
(byte) 0xff, (byte) 0xff, 0x55, 0x00,
|
||||
|
||||
0x00, 0x00, (byte) 0xaa, 0x00,
|
||||
0x55, 0x00, (byte) 0xaa, 0x00,
|
||||
(byte) 0xaa, 0x00, (byte) 0xaa, 0x00,
|
||||
(byte) 0xff, 0x00, (byte) 0xaa, 0x00,
|
||||
|
||||
0x00, 0x55, (byte) 0xaa, 0x00,
|
||||
0x55, 0x55, (byte) 0xaa, 0x00,
|
||||
(byte) 0xaa, 0x55, (byte) 0xaa, 0x00,
|
||||
(byte) 0xff, 0x55, (byte) 0xaa, 0x00,
|
||||
|
||||
0x00, (byte) 0xaa, (byte) 0xaa, 0x00,
|
||||
0x55, (byte) 0xaa, (byte) 0xaa, 0x00,
|
||||
(byte) 0xaa, (byte) 0xaa, (byte) 0xaa, 0x00,
|
||||
(byte) 0xff, (byte) 0xaa, (byte) 0xaa, 0x00,
|
||||
|
||||
0x00, (byte) 0xff, (byte) 0xaa, 0x00,
|
||||
0x55, (byte) 0xff, (byte) 0xaa, 0x00,
|
||||
(byte) 0xaa, (byte) 0xff, (byte) 0xaa, 0x00,
|
||||
(byte) 0xff, (byte) 0xff, (byte) 0xaa, 0x00,
|
||||
|
||||
0x00, 0x00, (byte) 0xff, 0x00,
|
||||
0x55, 0x00, (byte) 0xff, 0x00,
|
||||
(byte) 0xaa, 0x00, (byte) 0xff, 0x00,
|
||||
(byte) 0xff, 0x00, (byte) 0xff, 0x00,
|
||||
|
||||
0x00, 0x55, (byte) 0xff, 0x00,
|
||||
0x55, 0x55, (byte) 0xff, 0x00,
|
||||
(byte) 0xaa, 0x55, (byte) 0xff, 0x00,
|
||||
(byte) 0xff, 0x55, (byte) 0xff, 0x00,
|
||||
|
||||
0x00, (byte) 0xaa, (byte) 0xff, 0x00,
|
||||
0x55, (byte) 0xaa, (byte) 0xff, 0x00,
|
||||
(byte) 0xaa, (byte) 0xaa, (byte) 0xff, 0x00,
|
||||
(byte) 0xff, (byte) 0xaa, (byte) 0xff, 0x00,
|
||||
|
||||
0x00, (byte) 0xff, (byte) 0xff, 0x00,
|
||||
0x55, (byte) 0xff, (byte) 0xff, 0x00,
|
||||
(byte) 0xaa, (byte) 0xff, (byte) 0xff, 0x00,
|
||||
(byte) 0xff, (byte) 0xff, (byte) 0xff, 0x00,
|
||||
|
||||
};
|
||||
|
||||
|
||||
byte last_id = -1;
|
||||
private ArrayList<UUID> tmpUUIDS = new ArrayList<>();
|
||||
|
||||
@ -477,7 +568,7 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
||||
buf.putInt(timestamp); // 32-bit timestamp
|
||||
buf.putShort((short) 0); // duration
|
||||
buf.put((byte) 0x01); // type (0x01 = notification)
|
||||
buf.putShort((short) 0x0001); // flags 0x0001 = ?
|
||||
buf.putShort((short) 0x001f); // flags 0x0001 = ?
|
||||
buf.put((byte) 0x04); // layout (0x04 = notification?)
|
||||
buf.putShort(attributes_length); // total length of all attributes and actions in bytes
|
||||
buf.put(attributes_count);
|
||||
@ -506,7 +597,7 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
||||
|
||||
if (mForceProtocol) {
|
||||
// ACTION
|
||||
buf.put((byte) 0x01); // id
|
||||
buf.put((byte) 0x00); // id
|
||||
buf.put((byte) 0x04); // dismiss action
|
||||
buf.put((byte) 0x01); // number attributes
|
||||
buf.put((byte) 0x01); // attribute id (title)
|
||||
@ -921,34 +1012,38 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
||||
byte result = buf.get();
|
||||
mDevEventScreenshot = new GBDeviceEventScreenshot();
|
||||
int version = buf.getInt();
|
||||
if (result != 0 || version != 1) { // pebble time not yet
|
||||
if (result != 0) {
|
||||
return null;
|
||||
}
|
||||
mDevEventScreenshot.width = buf.getInt();
|
||||
mDevEventScreenshot.height = buf.getInt();
|
||||
mDevEventScreenshot.bpp = 1;
|
||||
mDevEventScreenshot.clut = new byte[]{
|
||||
0x00, 0x00, 0x00, 0x00, (byte) 0xff,
|
||||
(byte) 0xff, (byte) 0xff, 0x00
|
||||
};
|
||||
|
||||
mScreenshotRemaining = (mDevEventScreenshot.width * mDevEventScreenshot.height) / 8;
|
||||
if (mScreenshotRemaining > 50000) {
|
||||
mScreenshotRemaining = -1; // ignore too big values
|
||||
return null;
|
||||
if (version == 1) {
|
||||
mDevEventScreenshot.bpp = 1;
|
||||
mDevEventScreenshot.clut = clut_pebble;
|
||||
} else {
|
||||
mDevEventScreenshot.bpp = 8;
|
||||
mDevEventScreenshot.clut = clut_pebbletime;
|
||||
}
|
||||
|
||||
mScreenshotRemaining = (mDevEventScreenshot.width * mDevEventScreenshot.height * mDevEventScreenshot.bpp) / 8;
|
||||
|
||||
mDevEventScreenshot.data = new byte[mScreenshotRemaining];
|
||||
length -= 13;
|
||||
}
|
||||
if (mScreenshotRemaining == -1) {
|
||||
return null;
|
||||
}
|
||||
|
||||
for (int i = 0; i < length; i++) {
|
||||
byte corrected = reverseBits(buf.get());
|
||||
mDevEventScreenshot.data[mDevEventScreenshot.data.length - mScreenshotRemaining + i] = corrected;
|
||||
byte corrected = buf.get();
|
||||
if (mDevEventScreenshot.bpp == 1) {
|
||||
corrected = reverseBits(corrected);
|
||||
} else {
|
||||
corrected = (byte) (corrected & 0b00111111);
|
||||
}
|
||||
|
||||
mDevEventScreenshot.data[mDevEventScreenshot.data.length - mScreenshotRemaining + i] = corrected;
|
||||
}
|
||||
mScreenshotRemaining -= length;
|
||||
LOG.info("Screenshot remaining bytes " + mScreenshotRemaining);
|
||||
if (mScreenshotRemaining == 0) {
|
||||
|
@ -151,16 +151,16 @@ public class GB {
|
||||
headerbuf.putInt(screenshot.width);
|
||||
headerbuf.putInt(-screenshot.height);
|
||||
headerbuf.putShort((short) 1); // planes
|
||||
headerbuf.putShort((short) 1); // bit count
|
||||
headerbuf.putShort((short) screenshot.bpp);
|
||||
headerbuf.putInt(0); // compression
|
||||
headerbuf.putInt(0); // length of pixeldata in byte (uncompressed=0)
|
||||
headerbuf.putInt(0); // pixels per meter (x)
|
||||
headerbuf.putInt(0); // pixels per meter (y)
|
||||
headerbuf.putInt(2); // number of colors in CLUT
|
||||
headerbuf.putInt(2); // numbers of used colors
|
||||
headerbuf.putInt(screenshot.clut.length / 4); // number of colors in CLUT
|
||||
headerbuf.putInt(0); // numbers of used colors
|
||||
headerbuf.put(screenshot.clut);
|
||||
fos.write(headerbuf.array());
|
||||
int rowbytes = screenshot.width / 8;
|
||||
int rowbytes = (screenshot.width * screenshot.bpp) / 8;
|
||||
byte[] pad = new byte[rowbytes % 4];
|
||||
for (int i = 0; i < screenshot.height; i++) {
|
||||
fos.write(screenshot.data, rowbytes * i, rowbytes);
|
||||
|
Loading…
Reference in New Issue
Block a user