Merge pull request #3010 from Cacodemon345/qt-wacom-serial

Add Wacom SD-510C tablet emulation
This commit is contained in:
Miran Grča
2023-03-01 04:25:40 +01:00
committed by GitHub
23 changed files with 604 additions and 19 deletions

View File

@@ -1130,6 +1130,8 @@ pc_reset_hard_init(void)
#endif
update_mouse_msg();
ui_hard_reset_completed();
}
void
@@ -1277,7 +1279,7 @@ pc_run(void)
}
if (title_update) {
mouse_msg_idx = (mouse_type == MOUSE_TYPE_NONE) ? 2 : !!mouse_capture;
mouse_msg_idx = ((mouse_type == MOUSE_TYPE_NONE) || (mouse_mode >= 1)) ? 2 : !!mouse_capture;
swprintf(temp, sizeof_w(temp), mouse_msg[mouse_msg_idx], fps);
#ifdef __APPLE__
/* Needed due to modifying the UI on the non-main thread is a big no-no. */

View File

@@ -656,6 +656,8 @@ load_input_devices(void)
}
}
}
tablet_tool_type = !!ini_section_get_int(cat, "tablet_tool_type", 1);
}
/* Load "Sound" section. */
@@ -2338,6 +2340,12 @@ save_input_devices(void)
}
}
if (tablet_tool_type != 1) {
ini_section_set_int(cat, "tablet_tool_type", tablet_tool_type);
} else {
ini_section_delete_var(cat, "tablet_tool_type");
}
ini_delete_section_if_empty(config, cat);
}

View File

@@ -463,7 +463,7 @@ device_poll(const device_t *d, int x, int y, int z, int b)
if (devices[c] != NULL) {
if (devices[c] == d) {
if (devices[c]->poll)
return (devices[c]->poll(x, y, z, b, device_priv[c]));
return (devices[c]->poll(x, y, z, b, 0, 0, device_priv[c]));
}
}
}

View File

@@ -20,7 +20,7 @@ add_library(dev OBJECT bugger.c cassette.c cartridge.c hasp.c hwm.c hwm_lm75.c h
postcard.c serial.c clock_ics9xxx.c isapnp.c i2c.c i2c_gpio.c
smbus_piix4.c smbus_ali7101.c keyboard.c keyboard_xt.c keyboard_at.c
mouse.c mouse_bus.c mouse_serial.c mouse_ps2.c phoenix_486_jumper.c
serial_passthrough.c)
mouse_wacom_tablet.c serial_passthrough.c)
if(ISAMEM_RAMPAGE)
target_compile_definitions(dev PRIVATE USE_ISAMEM_RAMPAGE)

View File

@@ -37,7 +37,14 @@ int mouse_type = 0;
int mouse_x,
mouse_y,
mouse_z,
mouse_buttons;
mouse_buttons,
mouse_mode,
mouse_tablet_in_proximity = 0,
tablet_tool_type = 1; /* 0 = Puck/Cursor, 1 = Pen */
double mouse_x_abs,
mouse_y_abs;
static const device_t mouse_none_device = {
.name = "None",
@@ -80,6 +87,7 @@ static mouse_t mouse_devices[] = {
{ &mouse_msserial_device },
{ &mouse_ltserial_device },
{ &mouse_ps2_device },
{ &mouse_wacom_device },
{ NULL }
// clang-format on
};
@@ -147,6 +155,7 @@ mouse_reset(void)
/* Clear local data. */
mouse_x = mouse_y = mouse_z = 0;
mouse_buttons = 0x00;
mouse_mode = 0;
/* If no mouse configured, we're done. */
if (mouse_type == 0)
@@ -184,7 +193,7 @@ mouse_process(void)
if ((mouse_dev_poll != NULL) || (mouse_curr->poll != NULL)) {
if (mouse_curr->poll != NULL)
mouse_curr->poll(mouse_x, mouse_y, mouse_z, mouse_buttons, mouse_priv);
mouse_curr->poll(mouse_x, mouse_y, mouse_z, mouse_buttons, mouse_x_abs, mouse_y_abs, mouse_priv);
else
mouse_dev_poll(mouse_x, mouse_y, mouse_z, mouse_buttons, mouse_priv);

View File

@@ -449,7 +449,7 @@ ms_write(uint16_t port, uint8_t val, void *priv)
/* The emulator calls us with an update on the host mouse device. */
static int
bm_poll(int x, int y, int z, int b, void *priv)
bm_poll(int x, int y, int z, int b, double abs_x, double abs_y, void *priv)
{
mouse_t *dev = (mouse_t *) priv;
int xor ;

View File

@@ -267,7 +267,7 @@ mouse_reset:
}
static int
ps2_poll(int x, int y, int z, int b, void *priv)
ps2_poll(int x, int y, int z, int b, double abs_x, double abs_y, void *priv)
{
mouse_t *dev = (mouse_t *) priv;

View File

@@ -511,7 +511,7 @@ sermouse_command_timer(void *priv)
}
static int
sermouse_poll(int x, int y, int z, int b, void *priv)
sermouse_poll(int x, int y, int z, int b, double abs_x, double abs_y, void *priv)
{
mouse_t *dev = (mouse_t *) priv;

View File

@@ -0,0 +1,432 @@
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <86box/86box.h>
#include <86box/device.h>
#include <86box/timer.h>
#include <86box/mouse.h>
#include <86box/serial.h>
#include <86box/plat.h>
#define FLAG_3BTN 0x20 /* enable 3-button mode */
enum wacom_modes
{
WACOM_MODE_SUPPRESSED = 0,
WACOM_MODE_POINT = 1,
WACOM_MODE_STREAM = 2,
WACOM_MODE_SWITCH = 3,
};
enum {
REPORT_PHASE_PREPARE,
REPORT_PHASE_TRANSMIT
};
typedef struct {
const char *name; /* name of this device */
int8_t type, /* type of this device */
port;
uint8_t flags, but, /* device flags */
status, format,
data_len, data[64],
data_rec[0x200];
int abs_x, abs_y,
rel_x, rel_y,
oldb, b;
int data_pos, data_rec_pos, mode, transmission_ongoing, transmission_format, interval;
int increment, suppressed_increment;
int transmission_stopped;
int reset;
int transmit_id, transmit_id_pending;
int pressure_mode;
int suppressed, measurement, always_report;
int remote_req, remote_mode;
int last_abs_x, last_abs_y; /* Suppressed/Increment Mode. */
uint32_t settings; /* Settings DWORD */
double transmit_period;
double old_tsc, reset_tsc;
pc_timer_t report_timer;
serial_t *serial;
} mouse_wacom_t;
static double
wacom_transmit_period(mouse_wacom_t *dev, int bps, int rps)
{
double dbps = (double) bps;
double temp = 0.0;
int word_len = 10;
if (rps == -1)
temp = (double) word_len;
else {
temp = (double) rps;
temp = (9600.0 - (temp * 33.0));
temp /= rps;
}
temp = (1000000.0 / dbps) * temp;
return temp;
}
static void
wacom_reset(mouse_wacom_t* wacom)
{
wacom->transmit_period = wacom_transmit_period(wacom, 9600, -1);
wacom->mode = WACOM_MODE_POINT;
wacom->data_pos = 0;
wacom->transmission_ongoing = 0;
wacom->mode = 0;
wacom->transmission_stopped = 0;
wacom->interval = 0;
wacom->transmit_id = 0;
wacom->format = 0; /* ASCII */
wacom->measurement = 1;
wacom->increment = wacom->suppressed_increment = 0;
wacom->reset_tsc = tsc;
wacom->remote_mode = wacom->remote_req = 0;
wacom->always_report = 0;
mouse_mode = 1;
}
static void
wacom_callback(struct serial_s *serial, void *priv)
{
mouse_wacom_t* wacom = (mouse_wacom_t*)priv;
wacom->transmit_period = wacom_transmit_period(wacom, 9600, -1);
timer_stop(&wacom->report_timer);
timer_on_auto(&wacom->report_timer, wacom->transmit_period);
}
static void
wacom_write(struct serial_s *serial, void *priv, uint8_t data)
{
mouse_wacom_t* wacom = (mouse_wacom_t*)priv;
static int special_command = 0;
if (data == '~') {
special_command = 1;
return;
}
if (special_command) {
switch (data) {
case '#':
{
if (!wacom->transmission_ongoing) wacom->transmit_id++;
break;
}
}
special_command = 0;
return;
}
if (data == '@') {
wacom->remote_req = 1;
wacom->remote_mode = 1;
return;
}
if (data == 0x13) {
wacom->transmission_stopped = 1;
return;
}
if (data == 0x11) {
wacom->transmission_stopped = 0;
wacom->remote_mode = wacom->remote_req = 0;
return;
}
wacom->data_rec[wacom->data_rec_pos++] = data;
if (data == '\r' || data == '\n') {
wacom->data_rec[wacom->data_rec_pos] = 0;
wacom->data_rec_pos = 0;
if (data == '\n') pclog("Wacom: written %s", wacom->data_rec);
else pclog("Wacom: written %s\n", wacom->data_rec);
if (!memcmp(wacom->data_rec, "AS", 2)) {
wacom->format = (wacom->data_rec[2] == '1');
wacom->transmission_ongoing = 0;
} else if (!memcmp(wacom->data_rec, "SR", 2)) {
wacom->mode = WACOM_MODE_STREAM;
wacom->suppressed_increment = 0;
} else if (!memcmp(wacom->data_rec, "IN", 2)) {
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] == '#') {
wacom_reset(wacom);
} else if (!memcmp(wacom->data_rec, "IT", 2)) {
sscanf((const char*)wacom->data_rec, "IT%d", &wacom->interval);
} else if (!memcmp(wacom->data_rec, "DE", 2)) {
sscanf((const char*)wacom->data_rec, "DE%d", &mouse_mode);
mouse_mode = !mouse_mode;
plat_mouse_capture(0);
} else if (!memcmp(wacom->data_rec, "SU", 2)) {
sscanf((const char*)wacom->data_rec, "SU%d", &wacom->suppressed_increment);
} else if (!memcmp(wacom->data_rec, "PH", 2)) {
sscanf((const char*)wacom->data_rec, "PH%d", &wacom->pressure_mode);
} else if (!memcmp(wacom->data_rec, "IC", 2)) {
sscanf((const char*)wacom->data_rec, "IC%d", &wacom->measurement);
} else if (!memcmp(wacom->data_rec, "AL", 2)) {
sscanf((const char*)wacom->data_rec, "AL%d", &wacom->always_report);
} else if (!memcmp(wacom->data_rec, "RQ", 2)) {
sscanf((const char*)wacom->data_rec, "RQ%d", &wacom->remote_mode);
if (wacom->remote_mode) wacom->remote_req = 1;
} else if (!memcmp(wacom->data_rec, "SP", 2)) {
wacom->transmission_stopped = 1;
} else if (!memcmp(wacom->data_rec, "ST", 2)){
wacom->transmission_stopped = 0;
wacom->remote_mode = wacom->remote_req = 0;
}
}
}
static int
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;
wacom->abs_x = abs_x * (wacom->measurement ? 4566. : 5800.);
wacom->abs_y = abs_y * (wacom->measurement ? 2972. : 3774.);
if (wacom->abs_x > (wacom->measurement ? 4566 : 5800)) wacom->abs_x = (wacom->measurement ? 4566 : 5800);
if (wacom->abs_y > (wacom->measurement ? 2972 : 3774)) wacom->abs_x = (wacom->measurement ? 2972 : 3774);
if (wacom->abs_x < 0) wacom->abs_x = 0;
if (wacom->abs_y < 0) wacom->abs_y = 0;
wacom->rel_x = x;
wacom->rel_y = y;
if (wacom->b != b) wacom->oldb = wacom->b;
wacom->b = b;
return (0);
}
static int
wacom_switch_off_to_on(int b, int oldb)
{
if (!(oldb & 0x1) && (b & 1)) return 1;
if (!(oldb & 0x2) && (b & 2)) return 1;
if (!(oldb & 0x4) && (b & 4)) return 1;
return 0;
}
static uint8_t
wacom_get_switch(int b)
{
if (b & 0x4) return 0x23;
if (b & 0x2) return 0x22;
if (b & 0x1) return 0x21;
return 0x00;
}
static void
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) {
wacom->transmission_format = 0;
snprintf((char*)wacom->data, sizeof(wacom->data), "~#SD51C V3.2.1.01\r");
return;
}
wacom->transmission_format = wacom->format;
wacom->last_abs_x = wacom->abs_x;
wacom->last_abs_y = wacom->abs_y;
wacom->remote_req = 0;
wacom->oldb = wacom->b;
if (wacom->format == 1) {
wacom->data[0] = 0xC0;
wacom->data[6] = wacom->pressure_mode ? ((wacom->b & 0x1) ? (uint8_t)31 : (uint8_t)-31) : wacom_get_switch(wacom->b);
wacom->data[5] = (y & 0x7F);
wacom->data[4] = ((y & 0x3F80) >> 7) & 0x7F;
wacom->data[3] = (((y & 0xC000) >> 14) & 3);
wacom->data[2] = (x & 0x7F);
wacom->data[1] = ((x & 0x3F80) >> 7) & 0x7F;
wacom->data[0] |= (((x & 0xC000) >> 14) & 3);
if (mouse_mode == 0) {
wacom->data[0] |= (!!(x < 0)) << 2;
wacom->data[3] |= (!!(y < 0)) << 2;
}
if (wacom->pressure_mode) {
wacom->data[0] |= 0x10;
wacom->data[6] &= 0x7F;
}
if (tablet_tool_type == 1) {
wacom->data[0] |= 0x20;
}
if (!mouse_tablet_in_proximity) {
wacom->data[0] &= ~0x40;
}
} else {
wacom->data[0] = 0;
snprintf((char*)wacom->data, sizeof(wacom->data), "*,%05d,%05d,%d\r\n",
wacom->abs_x, wacom->abs_y,
wacom->pressure_mode ? ((wacom->b & 0x1) ? (uint8_t)-31 : (uint8_t)15) : ((wacom->b & 0x1) ? 21 : 00));
}
}
extern double cpuclock;
static void
wacom_report_timer(void *priv)
{
mouse_wacom_t* wacom = (mouse_wacom_t*)priv;
double milisecond_diff = ((double)(tsc - wacom->old_tsc)) / cpuclock * 1000.0;
int relative_mode = (mouse_mode == 0);
int x = (relative_mode ? wacom->rel_x : wacom->abs_x);
int y = (relative_mode ? wacom->rel_y : wacom->abs_y);
int x_diff = abs(relative_mode ? wacom->rel_x : (wacom->abs_x - wacom->last_abs_x));
int y_diff = abs(relative_mode ? wacom->rel_y : (wacom->abs_y - wacom->last_abs_y));
int increment = wacom->suppressed_increment ? wacom->suppressed_increment : wacom->increment;
timer_on_auto(&wacom->report_timer, wacom->transmit_period);
if ((((double)(tsc - wacom->reset_tsc)) / cpuclock * 1000.0) <= 10)
return;
if (wacom->transmit_id && !wacom->transmission_ongoing)
goto transmit_prepare;
if (wacom->transmission_ongoing)
goto transmit;
else if (wacom->remote_mode && !wacom->remote_req)
return;
else {
if (wacom->remote_mode && wacom->remote_req) {
goto transmit_prepare;
}
if (wacom->transmission_stopped || (!mouse_tablet_in_proximity && !wacom->always_report))
return;
if (milisecond_diff >= (wacom->interval * 5)) {
wacom->old_tsc = tsc;
} else
return;
switch (wacom->mode) {
case WACOM_MODE_STREAM:
default:
break;
case WACOM_MODE_POINT:
{
if (!(wacom_switch_off_to_on(wacom->b, wacom->oldb)))
return;
break;
}
case WACOM_MODE_SWITCH:
{
if (!wacom->b)
return;
break;
}
}
if (increment && !(x_diff > increment || y_diff > increment)) {
if (wacom->suppressed_increment && (wacom->b == wacom->oldb))
return;
if (wacom->increment && !wacom_switch_off_to_on(wacom->b, wacom->oldb))
return;
}
}
transmit_prepare:
wacom_transmit_prepare(wacom, x, y);
transmit:
serial_write_fifo(wacom->serial, wacom->data[wacom->data_pos++]);
if ((wacom->transmission_format == 0 && wacom->data[wacom->data_pos] == 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;
}
return;
}
static void *
wacom_init(const device_t *info)
{
mouse_wacom_t *dev;
dev = (mouse_wacom_t *) calloc(1, sizeof(mouse_wacom_t));
dev->name = info->name;
dev->but = 3;
dev->port = device_get_config_int("port");
dev->serial = serial_attach(dev->port, wacom_callback, wacom_write, dev);
timer_add(&dev->report_timer, wacom_report_timer, dev, 0);
mouse_set_buttons(dev->but);
wacom_reset(dev);
return dev;
}
static void
wacom_speed_changed(void *priv)
{
mouse_wacom_t *dev = (mouse_wacom_t *) priv;
wacom_callback(dev->serial, dev);
}
static void
wacom_close(void *priv)
{
mouse_wacom_t *dev = (mouse_wacom_t *) priv;
/* Detach serial port from the mouse. */
if (dev && dev->serial && dev->serial->sd)
memset(dev->serial->sd, 0, sizeof(serial_device_t));
free(dev);
}
static const device_config_t wacom_config[] = {
// clang-format off
{
.name = "port",
.description = "Serial Port",
.type = CONFIG_SELECTION,
.default_string = "",
.default_int = 0,
.file_filter = "",
.spinner = { 0 },
.selection = {
{ .description = "COM1", .value = 0 },
{ .description = "COM2", .value = 1 },
{ .description = "COM3", .value = 2 },
{ .description = "COM4", .value = 3 },
{ .description = "" }
}
},
{ .name = "", .description = "", .type = CONFIG_END }
// clang-format on
};
const device_t mouse_wacom_device = {
.name = "Wacom SD-510C",
.internal_name = "wacom_serial",
.flags = DEVICE_COM,
.local = MOUSE_TYPE_WACOM,
.init = wacom_init,
.close = wacom_close,
.reset = NULL,
{ .poll = wacom_poll },
.speed_changed = wacom_speed_changed,
.force_redraw = NULL,
.config = wacom_config
};

View File

@@ -130,7 +130,7 @@ typedef struct _device_ {
void (*reset)(void *priv);
union {
int (*available)(void);
int (*poll)(int x, int y, int z, int b, void *priv);
int (*poll)(int x, int y, int z, int b, double abs_x, double abs_y, void *priv);
void (*register_pci_slot)(int device, int type, int inta, int intb, int intc, int intd, void *priv);
};
void (*speed_changed)(void *priv);

View File

@@ -34,6 +34,7 @@
#define MOUSE_TYPE_LOGITECH 9 /* Logitech 2-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_WACOM 12 /* WACOM tablet */
#define MOUSE_TYPE_ONBOARD 0x80 /* Mouse is an on-board version of one of the above. */
@@ -43,7 +44,11 @@ extern "C" {
extern int mouse_type;
extern int mouse_x, mouse_y, mouse_z;
extern int mouse_mode; /* 1 = Absolute, 0 = Relative */
extern int mouse_tablet_in_proximity;
extern double mouse_x_abs, mouse_y_abs;
extern int mouse_buttons;
extern int tablet_tool_type;
#ifdef EMU_DEVICE_H
extern const device_t *mouse_get_device(int mouse);
@@ -59,6 +64,7 @@ extern const device_t mouse_mssystems_device;
extern const device_t mouse_msserial_device;
extern const device_t mouse_ltserial_device;
extern const device_t mouse_ps2_device;
extern const device_t mouse_wacom_device;
#endif
extern void mouse_init(void);

View File

@@ -61,6 +61,7 @@ extern void ui_check_menu_item(int id, int checked);
extern wchar_t *ui_window_title(wchar_t *s);
extern void ui_status_update(void);
extern void ui_hard_reset_completed(void);
extern void ui_init_monitor(int monitor_index);
extern void ui_deinit_monitor(int monitor_index);
extern int ui_sb_find_part(int tag);

View File

@@ -250,7 +250,6 @@ main(int argc, char *argv[])
auto rawInputFilter = WindowsRawInputFilter::Register(main_window);
if (rawInputFilter) {
app.installNativeEventFilter(rawInputFilter.get());
QObject::disconnect(main_window, &MainWindow::pollMouse, 0, 0);
QObject::connect(main_window, &MainWindow::pollMouse, (WindowsRawInputFilter *) rawInputFilter.get(), &WindowsRawInputFilter::mousePoll, Qt::DirectConnection);
main_window->setSendKeyboardInput(false);
}

View File

@@ -44,6 +44,7 @@ extern "C" {
#endif
#include <86box/device.h>
#include <86box/video.h>
#include <86box/mouse.h>
#include <86box/machine.h>
#include <86box/vid_ega.h>
#include <86box/version.h>
@@ -193,6 +194,12 @@ MainWindow::MainWindow(QWidget *parent)
vmname.truncate(vmname.size() - 1);
this->setWindowTitle(QString("%1 - %2 %3").arg(vmname, EMU_NAME, EMU_VERSION_FULL));
connect(this, &MainWindow::hardResetCompleted, this, [this]() {
ui->actionMCA_devices->setVisible(machine_has_bus(machine, MACHINE_BUS_MCA));
QApplication::setOverrideCursor(Qt::ArrowCursor);
ui->menuTablet_tool->menuAction()->setVisible(mouse_mode >= 1);
});
connect(this, &MainWindow::showMessageForNonQtThread, this, &MainWindow::showMessage_, Qt::BlockingQueuedConnection);
connect(this, &MainWindow::setTitle, this, [this, toolbar_label](const QString &title) {
@@ -631,6 +638,16 @@ MainWindow::MainWindow(QWidget *parent)
}
});
#endif
actGroup = new QActionGroup(this);
actGroup->addAction(ui->actionCursor_Puck);
actGroup->addAction(ui->actionPen);
if (tablet_tool_type == 1) {
ui->actionPen->setChecked(true);
} else {
ui->actionCursor_Puck->setChecked(true);
}
}
void
@@ -2435,8 +2452,19 @@ MainWindow::on_actionApply_fullscreen_stretch_mode_when_maximized_triggered(bool
config_save();
}
void MainWindow::on_actionCursor_Puck_triggered()
{
tablet_tool_type = 0;
config_save();
}
void MainWindow::on_actionPen_triggered()
{
tablet_tool_type = 1;
config_save();
}
void MainWindow::on_actionACPI_Shutdown_triggered()
{
acpi_pwrbut_pressed = 1;
}

View File

@@ -50,6 +50,7 @@ signals:
void destroyRendererMonitor(int monitor_index);
void initRendererMonitorForNonQtThread(int monitor_index);
void destroyRendererMonitorForNonQtThread(int monitor_index);
void hardResetCompleted();
void setTitle(const QString &title);
void setFullscreen(bool state);
@@ -135,6 +136,11 @@ protected:
void changeEvent(QEvent *event) override;
private slots:
void on_actionPen_triggered();
private slots:
void on_actionCursor_Puck_triggered();
void on_actionACPI_Shutdown_triggered();
private slots:

View File

@@ -61,8 +61,16 @@
<property name="title">
<string>&amp;Action</string>
</property>
<widget class="QMenu" name="menuTablet_tool">
<property name="title">
<string>Tablet tool</string>
</property>
<addaction name="actionPen"/>
<addaction name="actionCursor_Puck"/>
</widget>
<addaction name="actionKeyboard_requires_capture"/>
<addaction name="actionRight_CTRL_is_left_ALT"/>
<addaction name="menuTablet_tool"/>
<addaction name="separator"/>
<addaction name="actionHard_Reset"/>
<addaction name="actionCtrl_Alt_Del"/>
@@ -851,6 +859,22 @@
<string>Apply fullscreen stretch mode when maximized</string>
</property>
</action>
<action name="actionCursor_Puck">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>Cursor/Puck</string>
</property>
</action>
<action name="actionPen">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>Pen</string>
</property>
</action>
</widget>
<customwidgets>
<customwidget>

View File

@@ -58,8 +58,10 @@ double mouse_x_error = 0.0, mouse_y_error = 0.0;
}
struct mouseinputdata {
atomic_int deltax, deltay, deltaz;
atomic_int mousebuttons;
atomic_int deltax, deltay, deltaz;
atomic_int mousebuttons;
atomic_bool mouse_tablet_in_proximity;
std::atomic<double> x_abs, y_abs;
};
static mouseinputdata mousedata;
@@ -116,6 +118,7 @@ RendererStack::RendererStack(QWidget *parent, int monitor_index)
RendererStack::~RendererStack()
{
QApplication::restoreOverrideCursor();
delete ui;
}
@@ -141,10 +144,17 @@ qt_mouse_capture(int on)
void
RendererStack::mousePoll()
{
#ifdef Q_OS_WINDOWS
if (mouse_mode == 0) {
mouse_x_abs = mousedata.x_abs;
mouse_y_abs = mousedata.y_abs;
return;
}
#endif
#ifndef __APPLE__
mouse_x = mousedata.deltax;
mouse_y = mousedata.deltay;
mouse_z = mousedata.deltaz;
mouse_x = mousedata.deltax;
mouse_y = mousedata.deltay;
mouse_z = mousedata.deltaz;
mousedata.deltax = mousedata.deltay = mousedata.deltaz = 0;
mouse_buttons = mousedata.mousebuttons;
@@ -152,6 +162,10 @@ RendererStack::mousePoll()
#endif
this->mouse_poll_func();
mouse_x_abs = mousedata.x_abs;
mouse_y_abs = mousedata.y_abs;
mouse_tablet_in_proximity = mousedata.mouse_tablet_in_proximity;
double scaled_x = mouse_x * mouse_sensitivity + mouse_x_error;
double scaled_y = mouse_y * mouse_sensitivity + mouse_y_error;
@@ -166,7 +180,7 @@ int ignoreNextMouseEvent = 1;
void
RendererStack::mouseReleaseEvent(QMouseEvent *event)
{
if (this->geometry().contains(event->pos()) && event->button() == Qt::LeftButton && !mouse_capture && (isMouseDown & 1) && (mouse_get_buttons() != 0)) {
if (this->geometry().contains(event->pos()) && event->button() == Qt::LeftButton && !mouse_capture && (isMouseDown & 1) && (mouse_get_buttons() != 0) && mouse_mode == 0) {
plat_mouse_capture(1);
this->setCursor(Qt::BlankCursor);
if (!ignoreNextMouseEvent)
@@ -180,7 +194,7 @@ RendererStack::mouseReleaseEvent(QMouseEvent *event)
isMouseDown &= ~1;
return;
}
if (mouse_capture) {
if (mouse_capture || mouse_mode >= 1) {
mousedata.mousebuttons &= ~event->button();
}
isMouseDown &= ~1;
@@ -190,7 +204,7 @@ void
RendererStack::mousePressEvent(QMouseEvent *event)
{
isMouseDown |= 1;
if (mouse_capture) {
if (mouse_capture || mouse_mode >= 1) {
mousedata.mousebuttons |= event->button();
}
event->accept();
@@ -238,9 +252,26 @@ RendererStack::mouseMoveEvent(QMouseEvent *event)
#endif
}
void
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
RendererStack::enterEvent(QEnterEvent *event)
#else
RendererStack::enterEvent(QEvent *event)
#endif
{
mousedata.mouse_tablet_in_proximity = 1;
if (mouse_mode == 1)
QApplication::setOverrideCursor(Qt::BlankCursor);
}
void
RendererStack::leaveEvent(QEvent *event)
{
mousedata.mouse_tablet_in_proximity = 0;
if (mouse_mode == 1)
QApplication::setOverrideCursor(Qt::ArrowCursor);
if (QApplication::platformName().contains("wayland")) {
event->accept();
return;
@@ -501,3 +532,16 @@ RendererStack::changeEvent(QEvent *event)
config_save();
}
}
bool
RendererStack::event(QEvent* event)
{
if (event->type() == QEvent::MouseMove) {
QMouseEvent* mouse_event = (QMouseEvent*)event;
if (mouse_mode >= 1) {
mousedata.x_abs = (mouse_event->localPos().x()) / (long double)width();
mousedata.y_abs = (mouse_event->localPos().y()) / (long double)height();
}
}
return QStackedWidget::event(event);
}

View File

@@ -6,6 +6,7 @@
#include <QKeyEvent>
#include <QStackedWidget>
#include <QWidget>
#include <QCursor>
#include <atomic>
#include <memory>
@@ -30,6 +31,11 @@ public:
void mouseReleaseEvent(QMouseEvent *event) override;
void mouseMoveEvent(QMouseEvent *event) override;
void wheelEvent(QWheelEvent *event) override;
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
void enterEvent(QEnterEvent *event) override;
#else
void enterEvent(QEvent *event) override;
#endif
void leaveEvent(QEvent *event) override;
void closeEvent(QCloseEvent *event) override;
void changeEvent(QEvent *event) override;
@@ -45,6 +51,7 @@ public:
{
event->ignore();
}
bool event(QEvent* event) override;
enum class Renderer {
Software,

View File

@@ -74,6 +74,12 @@ ui_window_title(wchar_t *str)
return str;
}
void
ui_hard_reset_completed()
{
emit main_window->hardResetCompleted();
}
extern "C" void
qt_blit(int x, int y, int w, int h, int monitor_index)
{

View File

@@ -383,6 +383,7 @@ WindowsRawInputFilter::mouse_handle(PRAWINPUT raw)
void
WindowsRawInputFilter::mousePoll()
{
if (mouse_mode >= 1) return;
if (mouse_capture || video_fullscreen) {
static int b = 0;

View File

@@ -1319,3 +1319,8 @@ void
ui_sb_mt32lcd(char *str)
{
}
void
ui_hard_reset_completed(void)
{
}

View File

@@ -596,6 +596,7 @@ DEVOBJ := bugger.o cartridge.o cassette.o hasp.o hwm.o hwm_lm75.o hwm_lm78.o hwm
mouse.o \
mouse_bus.o \
mouse_serial.o mouse_ps2.o \
mouse_wacom_tablet.o \
phoenix_486_jumper.o serial_passthrough.o
SIOOBJ := sio_acc3221.o sio_ali5123.o \

View File

@@ -1603,7 +1603,13 @@ void
ui_init_monitor(int monitor_index)
{
}
void
ui_deinit_monitor(int monitor_index)
{
}
void
ui_hard_reset_completed(void)
{
}