void spice_display_send_button(SpiceDisplay *display, int button, bool down) {
    SpiceDisplayPrivate *d = SPICE_DISPLAY_GET_PRIVATE(display);
    int button_mask;

    switch (button) {
    case SPICE_MOUSE_BUTTON_LEFT:
        button_mask = SPICE_MOUSE_BUTTON_MASK_LEFT;
        break;
    case SPICE_MOUSE_BUTTON_MIDDLE:
        button_mask = SPICE_MOUSE_BUTTON_MASK_MIDDLE;
        break;
    case SPICE_MOUSE_BUTTON_RIGHT:
        button_mask = SPICE_MOUSE_BUTTON_MASK_RIGHT;
        break;
    default:
        return;
    }

    if (down) {
        d->mouse_button_mask |= button_mask;
        if (d->inputs)
            spice_inputs_button_press(d->inputs, button, d->mouse_button_mask);
    } else {
        d->mouse_button_mask &= ~button_mask;
        if (d->inputs)
            spice_inputs_button_release(d->inputs, button,
                    d->mouse_button_mask);
    }
}
void spice_display_send_scroll(SpiceDisplay *display, int button, int count) {
    SpiceDisplayPrivate *d = SPICE_DISPLAY_GET_PRIVATE(display);

    if (d->inputs) {
        for (int i = 0; i < count; i++) {
            spice_inputs_button_press(d->inputs, button, d->mouse_button_mask);
            spice_inputs_button_release(d->inputs, button,
                    d->mouse_button_mask);
        }
    }
}
JNIEXPORT void JNICALL
Java_com_iiordanov_aSPICE_SpiceCommunicator_SpiceButtonEvent(JNIEnv * env, jobject  obj, jint x, jint y, jint metaState, jint type) {
    SpiceDisplay* display = global_display;
    SpiceDisplayPrivate *d = SPICE_DISPLAY_GET_PRIVATE(display);
    //char buf[60];
    //snprintf (buf, 60, "Pointer event: %d at x: %d, y: %d", type, x, y);
    //__android_log_write(6, "android-io", buf);

    if (!d->inputs || (x >= 0 && x < d->width && y >= 0 && y < d->height)) {

		gboolean down = (type & PTRFLAGS_DOWN) != 0;
		int mouseButton = type &~ PTRFLAGS_DOWN;
		int newMask = update_mask (mouseButton, down);

		gint dx;
		gint dy;
	    switch (d->mouse_mode) {
	    case SPICE_MOUSE_MODE_CLIENT:
	        //__android_log_write(6, "android-io", "spice mouse mode client");
			spice_inputs_position(d->inputs, x, y, d->channel_id, newMask);
	        break;
	    case SPICE_MOUSE_MODE_SERVER:
	        //__android_log_write(6, "android-io", "spice mouse mode server");
	        dx = d->mouse_last_x != -1 ? x - d->mouse_last_x : 0;
	        dy = d->mouse_last_y != -1 ? y - d->mouse_last_y : 0;
	        spice_inputs_motion(d->inputs, dx, dy, newMask);
	        d->mouse_last_x = x;
	        d->mouse_last_y = y;
	        break;
	    default:
	        g_warn_if_reached();
	        break;
	    }

		if (mouseButton != SPICE_MOUSE_BUTTON_INVALID) {
			if (down) {
			    //__android_log_write(6, "android-io", "Button press");
				spice_inputs_button_press(d->inputs, mouseButton, newMask);
			} else {
			    //__android_log_write(6, "android-io", "Button release");
			    // This sleep is an ugly hack to prevent stuck buttons after a drag/drop gesture.
			    usleep(50000);
				spice_inputs_button_release(d->inputs, mouseButton, newMask);
			}
		}
    }
}
void QSpiceInputsChannel::inputsButtonPress(int button, int button_state)
{
    spice_inputs_button_press((SpiceInputsChannel *) gobject, button, button_state);
}