Merge pull request #3173 from Cacodemon345/qt-wacom-serial
Add and enable Wacom ArtPad emulation
This commit is contained in:
@@ -87,6 +87,7 @@ static mouse_t mouse_devices[] = {
|
|||||||
{ &mouse_ltserial_device },
|
{ &mouse_ltserial_device },
|
||||||
{ &mouse_ps2_device },
|
{ &mouse_ps2_device },
|
||||||
{ &mouse_wacom_device },
|
{ &mouse_wacom_device },
|
||||||
|
{ &mouse_wacom_artpad_device },
|
||||||
{ NULL }
|
{ NULL }
|
||||||
// clang-format on
|
// clang-format on
|
||||||
};
|
};
|
||||||
|
@@ -9,6 +9,7 @@
|
|||||||
#include <86box/mouse.h>
|
#include <86box/mouse.h>
|
||||||
#include <86box/serial.h>
|
#include <86box/serial.h>
|
||||||
#include <86box/plat.h>
|
#include <86box/plat.h>
|
||||||
|
#include <86box/fifo8.h>
|
||||||
|
|
||||||
#define FLAG_3BTN 0x20 /* enable 3-button mode */
|
#define FLAG_3BTN 0x20 /* enable 3-button mode */
|
||||||
|
|
||||||
@@ -19,34 +20,112 @@ enum wacom_modes {
|
|||||||
WACOM_MODE_SWITCH = 3,
|
WACOM_MODE_SWITCH = 3,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum wacom_handshake_modes {
|
||||||
|
WACOM_HANDSHAKE_NONE = 0,
|
||||||
|
WACOM_HANDSHAKE_CTS = 1,
|
||||||
|
WACOM_HANDSHAKE_DTS = 2,
|
||||||
|
WACOM_HANDSHAKE_BOTH = 3,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum wacom_cmd_set {
|
||||||
|
WACOM_CMDSET_BITPAD = 0,
|
||||||
|
WACOM_CMDSET_MM1201 = 1,
|
||||||
|
WACOM_CMDSET_IIS = 2,
|
||||||
|
WACOM_CMDSET_IV = 3
|
||||||
|
};
|
||||||
|
|
||||||
|
enum wacom_tablet_type {
|
||||||
|
WACOM_TYPE_IISONLY = 0,
|
||||||
|
WACOM_TYPE_IV,
|
||||||
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
REPORT_PHASE_PREPARE,
|
REPORT_PHASE_PREPARE,
|
||||||
REPORT_PHASE_TRANSMIT
|
REPORT_PHASE_TRANSMIT
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef struct wacom_tablet_id {
|
||||||
|
char id[64];
|
||||||
|
int type;
|
||||||
|
} wacom_tablet_id;
|
||||||
|
|
||||||
|
static const wacom_tablet_id sd510_id = {
|
||||||
|
.id = "~#SD51C V3.2.1.01\r",
|
||||||
|
.type = WACOM_TYPE_IISONLY
|
||||||
|
};
|
||||||
|
|
||||||
|
static const wacom_tablet_id artpad_id = {
|
||||||
|
.id = "~#KT-0405-R00 V1.1-0\r",
|
||||||
|
.type = WACOM_TYPE_IV
|
||||||
|
};
|
||||||
|
|
||||||
|
static const uint32_t wacom_resolution_values[4] = {
|
||||||
|
500,
|
||||||
|
508,
|
||||||
|
1000,
|
||||||
|
1270
|
||||||
|
};
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
const char *name; /* name of this device */
|
const char *name; /* name of this device */
|
||||||
int8_t type, /* type of this device */
|
int8_t type, /* type of this device */
|
||||||
port;
|
port;
|
||||||
uint8_t flags, but, /* device flags */
|
uint8_t flags, but, /* device flags */
|
||||||
status, format,
|
status, bits,
|
||||||
data_len, data[64],
|
|
||||||
data_rec[0x200];
|
data_rec[0x200];
|
||||||
int abs_x, abs_y,
|
int abs_x, abs_y,
|
||||||
rel_x, rel_y,
|
rel_x, rel_y,
|
||||||
oldb, b;
|
oldb, b;
|
||||||
|
|
||||||
int data_pos, data_rec_pos, mode, transmission_ongoing, transmission_format, interval;
|
Fifo8 data;
|
||||||
|
|
||||||
|
int data_rec_pos, mode, interval;
|
||||||
int increment, suppressed_increment;
|
int increment, suppressed_increment;
|
||||||
int transmission_stopped;
|
int transmission_stopped;
|
||||||
int reset;
|
int reset;
|
||||||
int transmit_id, transmit_id_pending;
|
int transmit_id, transmit_id_pending;
|
||||||
int pressure_mode;
|
int pressure_mode;
|
||||||
int suppressed, measurement, always_report;
|
int suppressed, measurement;
|
||||||
int remote_req, remote_mode;
|
int remote_req;
|
||||||
|
|
||||||
|
uint32_t x_res, y_res;
|
||||||
|
const wacom_tablet_id* tablet_type;
|
||||||
|
|
||||||
int last_abs_x, last_abs_y; /* Suppressed/Increment Mode. */
|
int last_abs_x, last_abs_y; /* Suppressed/Increment Mode. */
|
||||||
|
union {
|
||||||
uint32_t settings; /* Settings DWORD */
|
uint32_t settings; /* Settings DWORD */
|
||||||
|
/* We don't target any architectures except x86/x64/ARM32/ARM64.
|
||||||
|
(The ABIs for those are explicit in little-endian bit ordering) */
|
||||||
|
struct {
|
||||||
|
uint8_t remote_mode : 1;
|
||||||
|
uint8_t bitpad_two_cursor_data : 1;
|
||||||
|
uint8_t mm961_orientation : 1;
|
||||||
|
uint8_t mm_command_set : 1;
|
||||||
|
uint8_t tilt : 1;
|
||||||
|
uint8_t multi_device : 1;
|
||||||
|
uint8_t reading_height : 1;
|
||||||
|
uint8_t pressure_sensitivity : 1;
|
||||||
|
|
||||||
|
uint8_t pnp : 1; /* Unused. */
|
||||||
|
uint8_t dummy : 1;
|
||||||
|
uint8_t terminator : 2;
|
||||||
|
uint8_t out_of_range_data : 1;
|
||||||
|
uint8_t origin_location : 1;
|
||||||
|
uint8_t resolution : 2;
|
||||||
|
|
||||||
|
uint8_t transfer_rate : 2;
|
||||||
|
uint8_t coord_sys : 1;
|
||||||
|
uint8_t output_format : 1;
|
||||||
|
uint8_t transfer_mode : 2;
|
||||||
|
uint8_t handshake : 2;
|
||||||
|
|
||||||
|
uint8_t stop_bits_conf : 1;
|
||||||
|
uint8_t data_bits_conf : 1;
|
||||||
|
uint8_t parity : 2;
|
||||||
|
uint8_t baud_rate : 2;
|
||||||
|
uint8_t cmd_set : 2;
|
||||||
|
} settings_bits;
|
||||||
|
};
|
||||||
|
|
||||||
double transmit_period;
|
double transmit_period;
|
||||||
double old_tsc, reset_tsc;
|
double old_tsc, reset_tsc;
|
||||||
@@ -55,12 +134,22 @@ typedef struct {
|
|||||||
serial_t *serial;
|
serial_t *serial;
|
||||||
} mouse_wacom_t;
|
} mouse_wacom_t;
|
||||||
|
|
||||||
|
static unsigned int
|
||||||
|
reverse(register unsigned int x)
|
||||||
|
{
|
||||||
|
x = (((x & 0xaaaaaaaa) >> 1) | ((x & 0x55555555) << 1));
|
||||||
|
x = (((x & 0xcccccccc) >> 2) | ((x & 0x33333333) << 2));
|
||||||
|
x = (((x & 0xf0f0f0f0) >> 4) | ((x & 0x0f0f0f0f) << 4));
|
||||||
|
x = (((x & 0xff00ff00) >> 8) | ((x & 0x00ff00ff) << 8));
|
||||||
|
return ((x >> 16) | (x << 16));
|
||||||
|
}
|
||||||
|
|
||||||
static double
|
static double
|
||||||
wacom_transmit_period(mouse_wacom_t *dev, int bps, int rps)
|
wacom_transmit_period(mouse_wacom_t *dev, int bps, int rps)
|
||||||
{
|
{
|
||||||
double dbps = (double) bps;
|
double dbps = (double) bps;
|
||||||
double temp = 0.0;
|
double temp = 0.0;
|
||||||
int word_len = 10;
|
int word_len = dev->bits;
|
||||||
|
|
||||||
if (rps == -1)
|
if (rps == -1)
|
||||||
temp = (double) word_len;
|
temp = (double) word_len;
|
||||||
@@ -74,24 +163,82 @@ wacom_transmit_period(mouse_wacom_t *dev, int bps, int rps)
|
|||||||
return temp;
|
return temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
wacom_process_settings_dword(mouse_wacom_t *wacom, uint32_t dword)
|
||||||
|
{
|
||||||
|
wacom->settings = dword;
|
||||||
|
|
||||||
|
wacom->mode = wacom->settings_bits.transfer_mode;
|
||||||
|
|
||||||
|
wacom->bits = 1 + 7 + wacom->settings_bits.data_bits_conf;
|
||||||
|
wacom->bits += 1 + wacom->settings_bits.stop_bits_conf;
|
||||||
|
if (wacom->settings_bits.parity == 2 && !(wacom->bits % 2)) {
|
||||||
|
wacom->bits++;
|
||||||
|
} else if (wacom->settings_bits.parity == 3 && (wacom->bits % 2)) {
|
||||||
|
wacom->bits++;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(wacom->settings_bits.baud_rate) {
|
||||||
|
case 0:
|
||||||
|
wacom->transmit_period = wacom_transmit_period(wacom, 2400, -1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
wacom->transmit_period = wacom_transmit_period(wacom, 4800, -1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
wacom->transmit_period = wacom_transmit_period(wacom, 9600, -1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 3:
|
||||||
|
wacom->transmit_period = wacom_transmit_period(wacom, 19200, -1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
mouse_mode = !wacom->settings_bits.coord_sys;
|
||||||
|
wacom->x_res = wacom->y_res = wacom_resolution_values[wacom->settings_bits.resolution];
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
wacom_reset(mouse_wacom_t *wacom)
|
wacom_reset(mouse_wacom_t *wacom)
|
||||||
{
|
{
|
||||||
wacom->transmit_period = wacom_transmit_period(wacom, 9600, -1);
|
wacom->transmit_period = wacom_transmit_period(wacom, 9600, -1);
|
||||||
wacom->mode = WACOM_MODE_POINT;
|
wacom->mode = WACOM_MODE_POINT;
|
||||||
wacom->data_pos = 0;
|
|
||||||
wacom->transmission_ongoing = 0;
|
|
||||||
wacom->transmission_stopped = 0;
|
wacom->transmission_stopped = 0;
|
||||||
wacom->interval = 0;
|
wacom->interval = 0;
|
||||||
wacom->transmit_id = 0;
|
wacom->transmit_id = 0;
|
||||||
wacom->format = 0; /* ASCII */
|
wacom->settings_bits.output_format = 1; /* ASCII */
|
||||||
|
wacom->settings_bits.cmd_set = 1;
|
||||||
wacom->measurement = 1;
|
wacom->measurement = 1;
|
||||||
wacom->increment = wacom->suppressed_increment = 0;
|
wacom->increment = wacom->suppressed_increment = 0;
|
||||||
wacom->reset_tsc = tsc;
|
wacom->reset_tsc = tsc;
|
||||||
wacom->remote_mode = wacom->remote_req = 0;
|
wacom->settings_bits.remote_mode = wacom->remote_req = 0;
|
||||||
wacom->always_report = 0;
|
wacom->settings_bits.out_of_range_data = 0;
|
||||||
|
|
||||||
mouse_mode = 1;
|
mouse_mode = 1;
|
||||||
|
wacom_process_settings_dword(wacom, 0xA21BC800);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
wacom_reset_artpad(mouse_wacom_t *wacom)
|
||||||
|
{
|
||||||
|
wacom->transmit_period = wacom_transmit_period(wacom, 9600, -1);
|
||||||
|
wacom->mode = WACOM_MODE_SUPPRESSED;
|
||||||
|
wacom->transmission_stopped = 0;
|
||||||
|
wacom->interval = 0;
|
||||||
|
wacom->transmit_id = 0;
|
||||||
|
wacom->settings_bits.output_format = 0; /* Binary */
|
||||||
|
wacom->measurement = 1;
|
||||||
|
wacom->increment = 0;
|
||||||
|
wacom->suppressed_increment = 1;
|
||||||
|
wacom->reset_tsc = tsc;
|
||||||
|
wacom->settings_bits.remote_mode = 0;
|
||||||
|
wacom->remote_req = 0;
|
||||||
|
wacom->settings_bits.out_of_range_data = 0;
|
||||||
|
|
||||||
|
wacom_process_settings_dword(wacom, 0xE203C000);
|
||||||
|
mouse_mode = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -99,7 +246,23 @@ wacom_callback(struct serial_s *serial, void *priv)
|
|||||||
{
|
{
|
||||||
mouse_wacom_t *wacom = (mouse_wacom_t *) priv;
|
mouse_wacom_t *wacom = (mouse_wacom_t *) priv;
|
||||||
|
|
||||||
|
switch(wacom->settings_bits.baud_rate) {
|
||||||
|
case 0:
|
||||||
|
wacom->transmit_period = wacom_transmit_period(wacom, 2400, -1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
wacom->transmit_period = wacom_transmit_period(wacom, 4800, -1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
wacom->transmit_period = wacom_transmit_period(wacom, 9600, -1);
|
wacom->transmit_period = wacom_transmit_period(wacom, 9600, -1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 3:
|
||||||
|
wacom->transmit_period = wacom_transmit_period(wacom, 19200, -1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
timer_stop(&wacom->report_timer);
|
timer_stop(&wacom->report_timer);
|
||||||
timer_on_auto(&wacom->report_timer, wacom->transmit_period);
|
timer_on_auto(&wacom->report_timer, wacom->transmit_period);
|
||||||
}
|
}
|
||||||
@@ -118,8 +281,15 @@ wacom_write(struct serial_s *serial, void *priv, uint8_t data)
|
|||||||
switch (data) {
|
switch (data) {
|
||||||
case '#':
|
case '#':
|
||||||
{
|
{
|
||||||
if (!wacom->transmission_ongoing)
|
wacom->transmit_id = 1;
|
||||||
wacom->transmit_id++;
|
break;
|
||||||
|
}
|
||||||
|
case 'C':
|
||||||
|
case '*':
|
||||||
|
case 'R':
|
||||||
|
{
|
||||||
|
wacom->data_rec[wacom->data_rec_pos++] = '~';
|
||||||
|
wacom->data_rec[wacom->data_rec_pos++] = data;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -129,7 +299,15 @@ wacom_write(struct serial_s *serial, void *priv, uint8_t data)
|
|||||||
|
|
||||||
if (data == '@') {
|
if (data == '@') {
|
||||||
wacom->remote_req = 1;
|
wacom->remote_req = 1;
|
||||||
wacom->remote_mode = 1;
|
wacom->settings_bits.remote_mode = 1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (data == '#' && wacom->tablet_type->type == WACOM_TYPE_IV) {
|
||||||
|
wacom_reset_artpad(wacom);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (data == '$') {
|
||||||
|
wacom_reset(wacom);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (data == 0x13) {
|
if (data == 0x13) {
|
||||||
@@ -138,7 +316,7 @@ wacom_write(struct serial_s *serial, void *priv, uint8_t data)
|
|||||||
}
|
}
|
||||||
if (data == 0x11) {
|
if (data == 0x11) {
|
||||||
wacom->transmission_stopped = 0;
|
wacom->transmission_stopped = 0;
|
||||||
wacom->remote_mode = wacom->remote_req = 0;
|
wacom->settings_bits.remote_mode = wacom->remote_req = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
wacom->data_rec[wacom->data_rec_pos++] = data;
|
wacom->data_rec[wacom->data_rec_pos++] = data;
|
||||||
@@ -150,39 +328,72 @@ wacom_write(struct serial_s *serial, void *priv, uint8_t data)
|
|||||||
pclog("Wacom: written %s", wacom->data_rec);
|
pclog("Wacom: written %s", wacom->data_rec);
|
||||||
else
|
else
|
||||||
pclog("Wacom: written %s\n", wacom->data_rec);
|
pclog("Wacom: written %s\n", wacom->data_rec);
|
||||||
if (!memcmp(wacom->data_rec, "AS", 2)) {
|
if (!memcmp(wacom->data_rec, "AS", 2) && wacom->settings_bits.cmd_set == WACOM_CMDSET_IIS) {
|
||||||
wacom->format = (wacom->data_rec[2] == '1');
|
wacom->settings_bits.output_format = !(wacom->data_rec[2] == '1');
|
||||||
wacom->transmission_ongoing = 0;
|
|
||||||
} else if (!memcmp(wacom->data_rec, "SR", 2)) {
|
} else if (!memcmp(wacom->data_rec, "SR", 2)) {
|
||||||
wacom->mode = WACOM_MODE_STREAM;
|
wacom->mode = WACOM_MODE_STREAM;
|
||||||
wacom->suppressed_increment = 0;
|
|
||||||
} else if (!memcmp(wacom->data_rec, "IN", 2)) {
|
} else if (!memcmp(wacom->data_rec, "IN", 2)) {
|
||||||
sscanf((const char *) wacom->data_rec, "IN%d", &wacom->increment);
|
sscanf((const char *) wacom->data_rec, "IN%d", &wacom->increment);
|
||||||
} else if (!memcmp(wacom->data_rec, "RE", 2) || wacom->data_rec[0] == '$' || wacom->data_rec[0] == '#') {
|
} else if (!memcmp(wacom->data_rec, "RE", 2)) {
|
||||||
wacom_reset(wacom);
|
if (wacom->tablet_type->type == WACOM_TYPE_IV) wacom_reset_artpad(wacom);
|
||||||
|
else wacom_reset(wacom);
|
||||||
} else if (!memcmp(wacom->data_rec, "IT", 2)) {
|
} else if (!memcmp(wacom->data_rec, "IT", 2)) {
|
||||||
sscanf((const char *) wacom->data_rec, "IT%d", &wacom->interval);
|
sscanf((const char *) wacom->data_rec, "IT%d", &wacom->interval);
|
||||||
} else if (!memcmp(wacom->data_rec, "DE", 2)) {
|
} else if (!memcmp(wacom->data_rec, "DE", 2) && wacom->settings_bits.cmd_set == WACOM_CMDSET_IIS) {
|
||||||
sscanf((const char *) wacom->data_rec, "DE%d", &mouse_mode);
|
sscanf((const char *) wacom->data_rec, "DE%d", &mouse_mode);
|
||||||
mouse_mode = !mouse_mode;
|
mouse_mode = !mouse_mode;
|
||||||
plat_mouse_capture(0);
|
plat_mouse_capture(0);
|
||||||
} else if (!memcmp(wacom->data_rec, "SU", 2)) {
|
} else if (!memcmp(wacom->data_rec, "SU", 2)) {
|
||||||
sscanf((const char *) wacom->data_rec, "SU%d", &wacom->suppressed_increment);
|
sscanf((const char *) wacom->data_rec, "SU%d", &wacom->suppressed_increment);
|
||||||
} else if (!memcmp(wacom->data_rec, "PH", 2)) {
|
wacom->settings_bits.transfer_mode = wacom->mode = WACOM_MODE_SUPPRESSED;
|
||||||
|
} else if (!memcmp(wacom->data_rec, "PH", 2) && wacom->settings_bits.cmd_set == WACOM_CMDSET_IIS) {
|
||||||
sscanf((const char *) wacom->data_rec, "PH%d", &wacom->pressure_mode);
|
sscanf((const char *) wacom->data_rec, "PH%d", &wacom->pressure_mode);
|
||||||
} else if (!memcmp(wacom->data_rec, "IC", 2)) {
|
} else if (!memcmp(wacom->data_rec, "IC", 2)) {
|
||||||
sscanf((const char *) wacom->data_rec, "IC%d", &wacom->measurement);
|
sscanf((const char *) wacom->data_rec, "IC%d", &wacom->measurement);
|
||||||
|
} else if (!memcmp(wacom->data_rec, "SW", 2)) {
|
||||||
|
wacom->mode = WACOM_MODE_SWITCH;
|
||||||
} else if (!memcmp(wacom->data_rec, "AL", 2)) {
|
} else if (!memcmp(wacom->data_rec, "AL", 2)) {
|
||||||
sscanf((const char *) wacom->data_rec, "AL%d", &wacom->always_report);
|
uint8_t out_of_range_data = wacom->settings_bits.out_of_range_data;
|
||||||
|
wacom->settings_bits.out_of_range_data = !!out_of_range_data;
|
||||||
} else if (!memcmp(wacom->data_rec, "RQ", 2)) {
|
} else if (!memcmp(wacom->data_rec, "RQ", 2)) {
|
||||||
sscanf((const char *) wacom->data_rec, "RQ%d", &wacom->remote_mode);
|
uint8_t remote_mode = 0;
|
||||||
if (wacom->remote_mode)
|
sscanf((const char *) wacom->data_rec, "RQ%d", &remote_mode);
|
||||||
|
wacom->settings_bits.remote_mode = !!remote_mode;
|
||||||
|
if (wacom->settings_bits.remote_mode)
|
||||||
wacom->remote_req = 1;
|
wacom->remote_req = 1;
|
||||||
} else if (!memcmp(wacom->data_rec, "SP", 2)) {
|
} else if (!memcmp(wacom->data_rec, "SP", 2)) {
|
||||||
wacom->transmission_stopped = 1;
|
wacom->transmission_stopped = 1;
|
||||||
} else if (!memcmp(wacom->data_rec, "ST", 2)) {
|
} else if (!memcmp(wacom->data_rec, "ST", 2)) {
|
||||||
wacom->transmission_stopped = 0;
|
wacom->transmission_stopped = 0;
|
||||||
wacom->remote_mode = wacom->remote_req = 0;
|
wacom->settings_bits.remote_mode = wacom->remote_req = 0;
|
||||||
|
} else if (!memcmp(wacom->data_rec, "NR", 2)) {
|
||||||
|
sscanf((const char *) wacom->data_rec, "NR%d", &wacom->x_res);
|
||||||
|
wacom->y_res = wacom->x_res;
|
||||||
|
} else if (wacom->tablet_type->type == WACOM_TYPE_IV && wacom->data_rec[0] == '~') {
|
||||||
|
if (!memcmp(wacom->data_rec, "~*", 2)) {
|
||||||
|
uint32_t settings_dword = wacom->settings;
|
||||||
|
if (strstr(wacom->data_rec, ",")) {
|
||||||
|
uint32_t x_res = wacom->x_res, y_res = wacom->y_res;
|
||||||
|
uint32_t increment = wacom->increment;
|
||||||
|
uint32_t interval = wacom->interval;
|
||||||
|
|
||||||
|
sscanf("~*%08X,%d,%d,%d,%d", wacom->data_rec, &settings_dword, &increment, &interval, &x_res, &y_res);
|
||||||
|
|
||||||
|
wacom->interval = interval;
|
||||||
|
wacom->increment = increment;
|
||||||
|
wacom->x_res = x_res;
|
||||||
|
wacom->y_res = y_res;
|
||||||
|
} else {
|
||||||
|
sscanf("~*%X", wacom->data_rec, &settings_dword);
|
||||||
|
}
|
||||||
|
wacom_process_settings_dword(wacom, settings_dword);
|
||||||
|
} else if (!memcmp(wacom->data_rec, "~C", 2)) {
|
||||||
|
fifo8_push_all(&wacom->data, "~C5039,3779\r", sizeof("~C5039,3779\r") - 1);
|
||||||
|
} else if (!memcmp(wacom->data_rec, "~R", 2)) {
|
||||||
|
uint8_t data[256] = { 0 };
|
||||||
|
snprintf(data, sizeof(data), "~*%08X,%d,%d,%d,%d\r", wacom->settings, wacom->increment, wacom->x_res, wacom->y_res);
|
||||||
|
fifo8_push_all(&wacom->data, data, strlen(data));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -191,6 +402,11 @@ static int
|
|||||||
wacom_poll(int x, int y, int z, int b, double abs_x, double abs_y, void *priv)
|
wacom_poll(int x, int y, int z, int b, double abs_x, double abs_y, void *priv)
|
||||||
{
|
{
|
||||||
mouse_wacom_t *wacom = (mouse_wacom_t *) priv;
|
mouse_wacom_t *wacom = (mouse_wacom_t *) priv;
|
||||||
|
|
||||||
|
if (wacom->settings_bits.cmd_set == WACOM_CMDSET_IV) {
|
||||||
|
wacom->abs_x = abs_x * 5039. * (wacom->x_res / 1000.);
|
||||||
|
wacom->abs_y = abs_y * 3779. * (wacom->y_res / 1000.);
|
||||||
|
} else {
|
||||||
wacom->abs_x = abs_x * (wacom->measurement ? 4566. : 5800.);
|
wacom->abs_x = abs_x * (wacom->measurement ? 4566. : 5800.);
|
||||||
wacom->abs_y = abs_y * (wacom->measurement ? 2972. : 3774.);
|
wacom->abs_y = abs_y * (wacom->measurement ? 2972. : 3774.);
|
||||||
if (wacom->abs_x > (wacom->measurement ? 4566 : 5800))
|
if (wacom->abs_x > (wacom->measurement ? 4566 : 5800))
|
||||||
@@ -203,6 +419,7 @@ wacom_poll(int x, int y, int z, int b, double abs_x, double abs_y, void *priv)
|
|||||||
wacom->abs_y = 0;
|
wacom->abs_y = 0;
|
||||||
wacom->rel_x = x;
|
wacom->rel_x = x;
|
||||||
wacom->rel_y = y;
|
wacom->rel_y = y;
|
||||||
|
}
|
||||||
if (wacom->b != b)
|
if (wacom->b != b)
|
||||||
wacom->oldb = wacom->b;
|
wacom->oldb = wacom->b;
|
||||||
wacom->b = b;
|
wacom->b = b;
|
||||||
@@ -238,54 +455,72 @@ wacom_get_switch(int b)
|
|||||||
static void
|
static void
|
||||||
wacom_transmit_prepare(mouse_wacom_t *wacom, int x, int y)
|
wacom_transmit_prepare(mouse_wacom_t *wacom, int x, int y)
|
||||||
{
|
{
|
||||||
wacom->transmission_ongoing = 1;
|
|
||||||
wacom->data_pos = 0;
|
|
||||||
memset(wacom->data, 0, sizeof(wacom->data));
|
|
||||||
if (wacom->transmit_id) {
|
if (wacom->transmit_id) {
|
||||||
wacom->transmission_format = 0;
|
uint8_t data[128] = { 0 };
|
||||||
snprintf((char *) wacom->data, sizeof(wacom->data), "~#SD51C V3.2.1.01\r");
|
snprintf((char *) data, sizeof(data), "%s", wacom->tablet_type->id);
|
||||||
|
fifo8_push_all(&wacom->data, data, strlen(data));
|
||||||
|
wacom->transmit_id = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
wacom->transmission_format = wacom->format;
|
|
||||||
wacom->last_abs_x = wacom->abs_x;
|
wacom->last_abs_x = wacom->abs_x;
|
||||||
wacom->last_abs_y = wacom->abs_y;
|
wacom->last_abs_y = wacom->abs_y;
|
||||||
wacom->remote_req = 0;
|
wacom->remote_req = 0;
|
||||||
|
|
||||||
wacom->oldb = wacom->b;
|
wacom->oldb = wacom->b;
|
||||||
if (wacom->format == 1) {
|
if (wacom->settings_bits.output_format == 0) {
|
||||||
wacom->data[0] = 0xC0;
|
uint8_t data[7];
|
||||||
wacom->data[6] = wacom->pressure_mode ? ((wacom->b & 0x1) ? (uint8_t) 31 : (uint8_t) -31) : wacom_get_switch(wacom->b);
|
data[0] = 0xC0;
|
||||||
|
if (wacom->settings_bits.cmd_set == WACOM_CMDSET_IV) {
|
||||||
|
if (tablet_tool_type == 0)
|
||||||
|
data[6] = ((wacom->b & 0x1) ? (uint8_t) 31 : (uint8_t) -1);
|
||||||
|
else
|
||||||
|
data[6] = ((wacom->b & 0x1) ? (uint8_t) 63 : (uint8_t) -63);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
data[6] = (wacom->pressure_mode || wacom->settings_bits.cmd_set == WACOM_CMDSET_IV) ? ((wacom->b & 0x1) ? (uint8_t) 31 : (uint8_t) -31) : wacom_get_switch(wacom->b);
|
||||||
|
|
||||||
wacom->data[5] = (y & 0x7F);
|
data[5] = (y & 0x7F);
|
||||||
wacom->data[4] = ((y & 0x3F80) >> 7) & 0x7F;
|
data[4] = ((y & 0x3F80) >> 7) & 0x7F;
|
||||||
wacom->data[3] = (((y & 0xC000) >> 14) & 3);
|
data[3] = (((y & 0xC000) >> 14) & 3);
|
||||||
|
|
||||||
wacom->data[2] = (x & 0x7F);
|
data[2] = (x & 0x7F);
|
||||||
wacom->data[1] = ((x & 0x3F80) >> 7) & 0x7F;
|
data[1] = ((x & 0x3F80) >> 7) & 0x7F;
|
||||||
wacom->data[0] |= (((x & 0xC000) >> 14) & 3);
|
data[0] |= (((x & 0xC000) >> 14) & 3);
|
||||||
|
|
||||||
if (mouse_mode == 0) {
|
if (mouse_mode == 0 && wacom->settings_bits.cmd_set == WACOM_CMDSET_IIS) {
|
||||||
wacom->data[0] |= (!!(x < 0)) << 2;
|
data[0] |= (!!(x < 0)) << 2;
|
||||||
wacom->data[3] |= (!!(y < 0)) << 2;
|
data[3] |= (!!(y < 0)) << 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wacom->pressure_mode) {
|
if (wacom->settings_bits.cmd_set == WACOM_CMDSET_IV) {
|
||||||
wacom->data[0] |= 0x10;
|
data[6] &= 0x7F;
|
||||||
wacom->data[6] &= 0x7F;
|
data[3] &= 0x3;
|
||||||
|
if (wacom_get_switch(wacom->b) != 0x21) {
|
||||||
|
data[3] |= (wacom_get_switch(wacom->b) & 0xF) << 3;
|
||||||
|
data[0] |= 0x8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wacom->pressure_mode && wacom->settings_bits.cmd_set == WACOM_CMDSET_IIS) {
|
||||||
|
data[0] |= 0x10;
|
||||||
|
data[6] &= 0x7F;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tablet_tool_type == 1) {
|
if (tablet_tool_type == 1) {
|
||||||
wacom->data[0] |= 0x20;
|
data[0] |= 0x20;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!mouse_tablet_in_proximity) {
|
if (!mouse_tablet_in_proximity) {
|
||||||
wacom->data[0] &= ~0x40;
|
data[0] &= ~0x40;
|
||||||
}
|
}
|
||||||
|
fifo8_push_all(&wacom->data, data, 7);
|
||||||
} else {
|
} else {
|
||||||
wacom->data[0] = 0;
|
uint8_t data[128];
|
||||||
snprintf((char *) wacom->data, sizeof(wacom->data), "*,%05d,%05d,%d\r\n",
|
data[0] = 0;
|
||||||
|
snprintf((char *) data, sizeof(data), "*,%05d,%05d,%d\r\n",
|
||||||
wacom->abs_x, wacom->abs_y,
|
wacom->abs_x, wacom->abs_y,
|
||||||
wacom->pressure_mode ? ((wacom->b & 0x1) ? (uint8_t) -31 : (uint8_t) 15) : ((wacom->b & 0x1) ? 21 : 00));
|
wacom->pressure_mode ? ((wacom->b & 0x1) ? (uint8_t) -31 : (uint8_t) 15) : ((wacom->b & 0x1) ? 21 : 00));
|
||||||
|
fifo8_push_all(&wacom->data, data, strlen(data));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -305,17 +540,17 @@ wacom_report_timer(void *priv)
|
|||||||
timer_on_auto(&wacom->report_timer, wacom->transmit_period);
|
timer_on_auto(&wacom->report_timer, wacom->transmit_period);
|
||||||
if ((((double) (tsc - wacom->reset_tsc)) / cpuclock * 1000.0) <= 10)
|
if ((((double) (tsc - wacom->reset_tsc)) / cpuclock * 1000.0) <= 10)
|
||||||
return;
|
return;
|
||||||
if (wacom->transmit_id && !wacom->transmission_ongoing)
|
if (wacom->transmit_id)
|
||||||
goto transmit_prepare;
|
goto transmit_prepare;
|
||||||
if (wacom->transmission_ongoing)
|
if (fifo8_num_used(&wacom->data))
|
||||||
goto transmit;
|
goto transmit;
|
||||||
else if (wacom->remote_mode && !wacom->remote_req)
|
else if (wacom->settings_bits.remote_mode && !wacom->remote_req)
|
||||||
return;
|
return;
|
||||||
else {
|
else {
|
||||||
if (wacom->remote_mode && wacom->remote_req) {
|
if (wacom->settings_bits.remote_mode && wacom->remote_req) {
|
||||||
goto transmit_prepare;
|
goto transmit_prepare;
|
||||||
}
|
}
|
||||||
if (wacom->transmission_stopped || (!mouse_tablet_in_proximity && !wacom->always_report))
|
if (wacom->transmission_stopped || (!mouse_tablet_in_proximity && !wacom->settings_bits.out_of_range_data))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (milisecond_diff >= (wacom->interval * 5)) {
|
if (milisecond_diff >= (wacom->interval * 5)) {
|
||||||
@@ -346,6 +581,9 @@ wacom_report_timer(void *priv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (increment && !mouse_tablet_in_proximity)
|
||||||
|
return;
|
||||||
|
|
||||||
if (increment && !(x_diff > increment || y_diff > increment)) {
|
if (increment && !(x_diff > increment || y_diff > increment)) {
|
||||||
if (wacom->suppressed_increment && (wacom->b == wacom->oldb))
|
if (wacom->suppressed_increment && (wacom->b == wacom->oldb))
|
||||||
return;
|
return;
|
||||||
@@ -359,12 +597,8 @@ transmit_prepare:
|
|||||||
wacom_transmit_prepare(wacom, x, y);
|
wacom_transmit_prepare(wacom, x, y);
|
||||||
|
|
||||||
transmit:
|
transmit:
|
||||||
serial_write_fifo(wacom->serial, wacom->data[wacom->data_pos++]);
|
serial_write_fifo(wacom->serial, fifo8_pop(&wacom->data));
|
||||||
if ((wacom->transmission_format == 0 && wacom->data[wacom->data_pos] == 0)
|
if (fifo8_num_used(&wacom->data) == 0) {
|
||||||
|| (wacom->transmission_format == 1 && wacom->data_pos == 7)) {
|
|
||||||
wacom->transmission_ongoing = 0;
|
|
||||||
wacom->transmit_id = 0;
|
|
||||||
wacom->data_pos = 0;
|
|
||||||
wacom->old_tsc = tsc;
|
wacom->old_tsc = tsc;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
@@ -378,6 +612,13 @@ wacom_init(const device_t *info)
|
|||||||
dev = (mouse_wacom_t *) calloc(1, sizeof(mouse_wacom_t));
|
dev = (mouse_wacom_t *) calloc(1, sizeof(mouse_wacom_t));
|
||||||
dev->name = info->name;
|
dev->name = info->name;
|
||||||
dev->but = 3;
|
dev->but = 3;
|
||||||
|
dev->bits = 10;
|
||||||
|
if (info->local == 0) {
|
||||||
|
dev->tablet_type = &sd510_id;
|
||||||
|
} else
|
||||||
|
dev->tablet_type = (wacom_tablet_id*)info->local;
|
||||||
|
|
||||||
|
fifo8_create(&dev->data, 512);
|
||||||
|
|
||||||
dev->port = device_get_config_int("port");
|
dev->port = device_get_config_int("port");
|
||||||
|
|
||||||
@@ -385,7 +626,11 @@ wacom_init(const device_t *info)
|
|||||||
timer_add(&dev->report_timer, wacom_report_timer, dev, 0);
|
timer_add(&dev->report_timer, wacom_report_timer, dev, 0);
|
||||||
mouse_set_buttons(dev->but);
|
mouse_set_buttons(dev->but);
|
||||||
|
|
||||||
wacom_reset(dev);
|
if (dev->tablet_type->type == WACOM_TYPE_IV) {
|
||||||
|
wacom_reset_artpad(dev);
|
||||||
|
wacom_process_settings_dword(dev, 0xE2018000);
|
||||||
|
}
|
||||||
|
else wacom_reset(dev);
|
||||||
|
|
||||||
return dev;
|
return dev;
|
||||||
}
|
}
|
||||||
@@ -403,6 +648,8 @@ wacom_close(void *priv)
|
|||||||
{
|
{
|
||||||
mouse_wacom_t *dev = (mouse_wacom_t *) priv;
|
mouse_wacom_t *dev = (mouse_wacom_t *) priv;
|
||||||
|
|
||||||
|
fifo8_destroy(&dev->data);
|
||||||
|
|
||||||
/* Detach serial port from the mouse. */
|
/* Detach serial port from the mouse. */
|
||||||
if (dev && dev->serial && dev->serial->sd)
|
if (dev && dev->serial && dev->serial->sd)
|
||||||
memset(dev->serial->sd, 0, sizeof(serial_device_t));
|
memset(dev->serial->sd, 0, sizeof(serial_device_t));
|
||||||
@@ -436,7 +683,21 @@ const device_t mouse_wacom_device = {
|
|||||||
.name = "Wacom SD-510C",
|
.name = "Wacom SD-510C",
|
||||||
.internal_name = "wacom_serial",
|
.internal_name = "wacom_serial",
|
||||||
.flags = DEVICE_COM,
|
.flags = DEVICE_COM,
|
||||||
.local = MOUSE_TYPE_WACOM,
|
.local = 0,
|
||||||
|
.init = wacom_init,
|
||||||
|
.close = wacom_close,
|
||||||
|
.reset = NULL,
|
||||||
|
{ .poll = wacom_poll },
|
||||||
|
.speed_changed = wacom_speed_changed,
|
||||||
|
.force_redraw = NULL,
|
||||||
|
.config = wacom_config
|
||||||
|
};
|
||||||
|
|
||||||
|
const device_t mouse_wacom_artpad_device = {
|
||||||
|
.name = "Wacom ArtPad",
|
||||||
|
.internal_name = "wacom_serial_artpad",
|
||||||
|
.flags = DEVICE_COM,
|
||||||
|
.local = (uintptr_t)&artpad_id,
|
||||||
.init = wacom_init,
|
.init = wacom_init,
|
||||||
.close = wacom_close,
|
.close = wacom_close,
|
||||||
.reset = NULL,
|
.reset = NULL,
|
||||||
|
@@ -35,6 +35,7 @@
|
|||||||
#define MOUSE_TYPE_LT3BUTTON 10 /* Logitech 3-button Serial Mouse */
|
#define MOUSE_TYPE_LT3BUTTON 10 /* Logitech 3-button Serial Mouse */
|
||||||
#define MOUSE_TYPE_PS2 11 /* PS/2 series Bus Mouse */
|
#define MOUSE_TYPE_PS2 11 /* PS/2 series Bus Mouse */
|
||||||
#define MOUSE_TYPE_WACOM 12 /* WACOM tablet */
|
#define MOUSE_TYPE_WACOM 12 /* WACOM tablet */
|
||||||
|
#define MOUSE_TYPE_WACOMARTP 13 /* WACOM tablet (ArtPad) */
|
||||||
|
|
||||||
#define MOUSE_TYPE_ONBOARD 0x80 /* Mouse is an on-board version of one of the above. */
|
#define MOUSE_TYPE_ONBOARD 0x80 /* Mouse is an on-board version of one of the above. */
|
||||||
|
|
||||||
@@ -65,6 +66,7 @@ extern const device_t mouse_msserial_device;
|
|||||||
extern const device_t mouse_ltserial_device;
|
extern const device_t mouse_ltserial_device;
|
||||||
extern const device_t mouse_ps2_device;
|
extern const device_t mouse_ps2_device;
|
||||||
extern const device_t mouse_wacom_device;
|
extern const device_t mouse_wacom_device;
|
||||||
|
extern const device_t mouse_wacom_artpad_device;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern void mouse_init(void);
|
extern void mouse_init(void);
|
||||||
|
Reference in New Issue
Block a user