mirror of
git://git.tartarus.org/simon/puzzles.git
synced 2025-04-21 16:05:44 -07:00
Sanitising the mouse input data was a good idea, but my
implementation sucked. Revise it completely. [originally from svn r5209]
This commit is contained in:
87
midend.c
87
midend.c
@ -279,54 +279,59 @@ int midend_process_key(midend_data *me, int x, int y, int button)
|
|||||||
* fix it _here_ in the common midend code so that it only has
|
* fix it _here_ in the common midend code so that it only has
|
||||||
* to be done once.
|
* to be done once.
|
||||||
*
|
*
|
||||||
* Semantics:
|
* The possible ways in which things can go screwy in the front
|
||||||
|
* end are:
|
||||||
*
|
*
|
||||||
* - when we receive a button down message, we remember which
|
* - in a system containing multiple physical buttons button
|
||||||
* button went down.
|
* presses can inadvertently overlap. We can see ABab (caps
|
||||||
|
* meaning button-down and lowercase meaning button-up) when
|
||||||
|
* the user had semantically intended AaBb.
|
||||||
*
|
*
|
||||||
* - if we receive a drag or release message for a button we
|
* - in a system where one button is simulated by means of a
|
||||||
* don't currently think is pressed, we fabricate a
|
* modifier key and another button, buttons can mutate
|
||||||
* button-down for it before sending it.
|
* between press and release (possibly during drag). So we
|
||||||
|
* can see Ab instead of Aa.
|
||||||
*
|
*
|
||||||
* - if we receive (or fabricate) a button down message
|
* Definite requirements are:
|
||||||
* without having seen a button up for the previously
|
*
|
||||||
* pressed button, we invent the button up before sending
|
* - button _presses_ must never be invented or destroyed. If
|
||||||
* the button down.
|
* the user presses two buttons in succession, the button
|
||||||
|
* presses must be transferred to the backend unchanged. So
|
||||||
|
* if we see AaBb , that's fine; if we see ABab (the button
|
||||||
|
* presses inadvertently overlapped) we must somehow
|
||||||
|
* `correct' it to AaBb.
|
||||||
|
*
|
||||||
|
* - every mouse action must end up looking like a press, zero
|
||||||
|
* or more drags, then a release. This allows back ends to
|
||||||
|
* make the _assumption_ that incoming mouse data will be
|
||||||
|
* sane in this regard, and not worry about the details.
|
||||||
|
*
|
||||||
|
* So my policy will be:
|
||||||
|
*
|
||||||
|
* - treat any button-up as a button-up for the currently
|
||||||
|
* pressed button, or ignore it if there is no currently
|
||||||
|
* pressed button.
|
||||||
|
*
|
||||||
|
* - treat any drag as a drag for the currently pressed
|
||||||
|
* button, or ignore it if there is no currently pressed
|
||||||
|
* button.
|
||||||
|
*
|
||||||
|
* - if we see a button-down while another button is currently
|
||||||
|
* pressed, invent a button-up for the first one and then
|
||||||
|
* pass the button-down through as before.
|
||||||
*
|
*
|
||||||
* Therefore, front ends can just send whatever data they
|
|
||||||
* happen to be conveniently able to get, and back ends can be
|
|
||||||
* guaranteed of always receiving a down, zero or more drags
|
|
||||||
* and an up for a single button at a time.
|
|
||||||
*/
|
*/
|
||||||
if (IS_MOUSE_DRAG(button) || IS_MOUSE_RELEASE(button)) {
|
if (IS_MOUSE_DRAG(button) || IS_MOUSE_RELEASE(button)) {
|
||||||
int which;
|
if (me->pressed_mouse_button) {
|
||||||
|
if (IS_MOUSE_DRAG(button)) {
|
||||||
if (IS_MOUSE_DRAG(button))
|
button = me->pressed_mouse_button +
|
||||||
which = button + (LEFT_BUTTON - LEFT_DRAG);
|
(LEFT_DRAG - LEFT_BUTTON);
|
||||||
else
|
} else {
|
||||||
which = button + (LEFT_BUTTON - LEFT_RELEASE);
|
button = me->pressed_mouse_button +
|
||||||
|
(LEFT_RELEASE - LEFT_BUTTON);
|
||||||
if (which != me->pressed_mouse_button) {
|
|
||||||
/*
|
|
||||||
* Fabricate a button-up for the currently pressed
|
|
||||||
* button, if any.
|
|
||||||
*/
|
|
||||||
if (me->pressed_mouse_button) {
|
|
||||||
ret = ret && midend_really_process_key
|
|
||||||
(me, x, y, (me->pressed_mouse_button +
|
|
||||||
(LEFT_RELEASE - LEFT_BUTTON)));
|
|
||||||
}
|
}
|
||||||
|
} else
|
||||||
/*
|
return ret; /* ignore it */
|
||||||
* Now fabricate a button-down for this one.
|
|
||||||
*/
|
|
||||||
ret = ret && midend_really_process_key(me, x, y, which);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* And set the currently pressed button to this one.
|
|
||||||
*/
|
|
||||||
me->pressed_mouse_button = which;
|
|
||||||
}
|
|
||||||
} else if (IS_MOUSE_DOWN(button) && me->pressed_mouse_button) {
|
} else if (IS_MOUSE_DOWN(button) && me->pressed_mouse_button) {
|
||||||
/*
|
/*
|
||||||
* Fabricate a button-up for the previously pressed button.
|
* Fabricate a button-up for the previously pressed button.
|
||||||
|
Reference in New Issue
Block a user