aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--devel.but38
-rw-r--r--emcc.c25
-rw-r--r--gtk.c14
-rw-r--r--midend.c38
-rw-r--r--nestedvm.c10
-rw-r--r--osx.m4
-rw-r--r--puzzles.h3
-rw-r--r--windows.c36
8 files changed, 97 insertions, 71 deletions
diff --git a/devel.but b/devel.but
index afc7fb1..65c1571 100644
--- a/devel.but
+++ b/devel.but
@@ -3291,8 +3291,7 @@ call to this function. Some back ends require that \cw{midend_size()}
\H{midend-process-key} \cw{midend_process_key()}
-\c bool midend_process_key(midend *me, int x, int y, int button,
-\c bool *handled);
+\c int midend_process_key(midend *me, int x, int y, int button)
The front end calls this function to report a mouse or keyboard event.
The parameters \c{x} and \c{y} are identical to the ones passed to the
@@ -3330,16 +3329,33 @@ Calling this function is very likely to result in calls back to the
front end's drawing API and/or \cw{activate_timer()}
(\k{frontend-activate-timer}).
-The return value from \cw{midend_process_key()} is \cw{true} unless
-the effect of the keypress was to request termination of the program.
-A front end should shut down the puzzle in response to a \cw{false}
-return.
+The return value from \cw{midend_process_key()} is one of the
+following constants:
-If the front end passes in a non-NULL pointer in \c{handled}, the
-mid-end will set \cw{*handled} to \cw{true} if it or the backend does
-something in response to the keypress. A front end can use this to
-decide whether to pass the keypress on to anything else that might
-want to do something in response to it.
+\dt \cw{PKR_QUIT}
+
+\dd Means that the effect of the keypress was to request termination
+of the program. A front end should shut down the puzzle in response
+to a \cw{PKR_QUIT} return.
+
+\dt \cw{PKR_SOME_EFFECT}
+
+\dd The keypress had some other effect, either in the mid-end or in
+the puzzle itself.
+
+\dt \cw{PKR_NO_EFFECT}
+
+\dd The keypress had no effect, but might have had an effect in
+slightly different circumstances. For instance it requested a move
+that wasn't possible.
+
+\dt \cw{PKR_UNUSED}
+
+\dd The key was one that neither the mid-end nor the back-end has any
+use for at all.
+
+A front end might respond to the last value by passing the key on to
+something else that might be interested in it.
The following additional values of \c{button} are permitted to be
passed to this function by the front end, but are never passed on to
diff --git a/emcc.c b/emcc.c
index 60ef8c8..7d7a09b 100644
--- a/emcc.c
+++ b/emcc.c
@@ -295,7 +295,7 @@ bool mousedown(int x, int y, int button)
button = (button == 0 ? LEFT_BUTTON :
button == 1 ? MIDDLE_BUTTON : RIGHT_BUTTON);
- midend_process_key(me, x, y, button, &handled);
+ handled = midend_process_key(me, x, y, button) != PKR_UNUSED;
post_move();
return handled;
}
@@ -306,7 +306,7 @@ bool mouseup(int x, int y, int button)
button = (button == 0 ? LEFT_RELEASE :
button == 1 ? MIDDLE_RELEASE : RIGHT_RELEASE);
- midend_process_key(me, x, y, button, &handled);
+ handled = midend_process_key(me, x, y, button) != PKR_UNUSED;
post_move();
return handled;
}
@@ -317,7 +317,7 @@ bool mousemove(int x, int y, int buttons)
buttons & 4 ? RIGHT_DRAG : LEFT_DRAG);
bool handled;
- midend_process_key(me, x, y, button, &handled);
+ handled = midend_process_key(me, x, y, button) != PKR_UNUSED;
post_move();
return handled;
}
@@ -335,7 +335,7 @@ bool key(int keycode, const char *key, const char *chr, int location,
#define DOM_KEY_LOCATION_RIGHT 2
#define DOM_KEY_LOCATION_NUMPAD 3
int keyevent = -1;
- bool handled;
+ int process_key_result;
if (!strnullcmp(key, "Backspace") || !strnullcmp(key, "Delete") ||
!strnullcmp(key, "Del"))
@@ -422,9 +422,16 @@ bool key(int keycode, const char *key, const char *chr, int location,
if (ctrl) keyevent |= MOD_CTRL;
if (location == DOM_KEY_LOCATION_NUMPAD) keyevent |= MOD_NUM_KEYPAD;
- midend_process_key(me, 0, 0, keyevent, &handled);
+ process_key_result = midend_process_key(me, 0, 0, keyevent);
post_move();
- return handled;
+ /*
+ * Treat Backspace specially because that's expected on KaiOS.
+ * https://developer.kaiostech.com/docs/design-guide/key
+ */
+ if (process_key_result == PKR_NO_EFFECT &&
+ !strnullcmp(key, "Backspace"))
+ return false;
+ return process_key_result != PKR_UNUSED;
}
return false; /* Event not handled, because we don't even recognise it. */
}
@@ -839,7 +846,7 @@ void command(int n)
post_move();
break;
case 5: /* New Game */
- midend_process_key(me, 0, 0, UI_NEWGAME, NULL);
+ midend_process_key(me, 0, 0, UI_NEWGAME);
post_move();
js_focus_canvas();
break;
@@ -849,12 +856,12 @@ void command(int n)
js_focus_canvas();
break;
case 7: /* Undo */
- midend_process_key(me, 0, 0, UI_UNDO, NULL);
+ midend_process_key(me, 0, 0, UI_UNDO);
post_move();
js_focus_canvas();
break;
case 8: /* Redo */
- midend_process_key(me, 0, 0, UI_REDO, NULL);
+ midend_process_key(me, 0, 0, UI_REDO);
post_move();
js_focus_canvas();
break;
diff --git a/gtk.c b/gtk.c
index 1c96270..035a300 100644
--- a/gtk.c
+++ b/gtk.c
@@ -1547,7 +1547,7 @@ static gint key_event(GtkWidget *widget, GdkEventKey *event, gpointer data)
keyval = -1;
if (keyval >= 0 &&
- !midend_process_key(fe->me, 0, 0, keyval, NULL))
+ midend_process_key(fe->me, 0, 0, keyval) == PKR_QUIT)
gtk_widget_destroy(fe->window);
return true;
@@ -1581,8 +1581,8 @@ static gint button_event(GtkWidget *widget, GdkEventButton *event,
if (event->type == GDK_BUTTON_RELEASE && button >= LEFT_BUTTON)
button += LEFT_RELEASE - LEFT_BUTTON;
- if (!midend_process_key(fe->me, event->x - fe->ox,
- event->y - fe->oy, button, NULL))
+ if (midend_process_key(fe->me, event->x - fe->ox,
+ event->y - fe->oy, button) == PKR_QUIT)
gtk_widget_destroy(fe->window);
return true;
@@ -1606,8 +1606,8 @@ static gint motion_event(GtkWidget *widget, GdkEventMotion *event,
else
return false; /* don't even know what button! */
- if (!midend_process_key(fe->me, event->x - fe->ox,
- event->y - fe->oy, button, NULL))
+ if (midend_process_key(fe->me, event->x - fe->ox,
+ event->y - fe->oy, button) == PKR_QUIT)
gtk_widget_destroy(fe->window);
#if GTK_CHECK_VERSION(2,12,0)
gdk_event_request_motions(event);
@@ -2210,7 +2210,7 @@ static void menu_key_event(GtkMenuItem *menuitem, gpointer data)
frontend *fe = (frontend *)data;
int key = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(menuitem),
"user-data"));
- if (!midend_process_key(fe->me, 0, 0, key, NULL))
+ if (midend_process_key(fe->me, 0, 0, key) == PKR_QUIT)
gtk_widget_destroy(fe->window);
}
@@ -4377,7 +4377,7 @@ int main(int argc, char **argv)
if (redo_proportion) {
/* Start a redo. */
- midend_process_key(fe->me, 0, 0, 'r', NULL);
+ midend_process_key(fe->me, 0, 0, 'r');
/* And freeze the timer at the specified position. */
midend_freeze_timer(fe->me, redo_proportion);
}
diff --git a/midend.c b/midend.c
index 1064af3..f9ebf77 100644
--- a/midend.c
+++ b/midend.c
@@ -973,13 +973,13 @@ void midend_restart_game(midend *me)
midend_set_timer(me);
}
-static bool midend_really_process_key(midend *me, int x, int y, int button,
- bool *handled)
+static int midend_really_process_key(midend *me, int x, int y, int button)
{
game_state *oldstate =
me->ourgame->dup_game(me->states[me->statepos - 1].state);
int type = MOVE;
- bool gottype = false, ret = true;
+ bool gottype = false;
+ int ret = PKR_NO_EFFECT;
float anim_time;
game_state *s;
char *movestr = NULL;
@@ -995,7 +995,7 @@ static bool midend_really_process_key(midend *me, int x, int y, int button,
button == '\x0E' || button == UI_NEWGAME) {
midend_new_game(me);
midend_redraw(me);
- *handled = true;
+ ret = PKR_SOME_EFFECT;
goto done; /* never animate */
} else if ((me->one_key_shortcuts && (button=='u' || button=='U')) ||
button == '*' || button == '\x1A' || button == '\x1F' ||
@@ -1005,30 +1005,32 @@ static bool midend_really_process_key(midend *me, int x, int y, int button,
gottype = true;
if (!midend_undo(me))
goto done;
- *handled = true;
+ ret = PKR_SOME_EFFECT;
} else if ((me->one_key_shortcuts && (button=='r' || button=='R')) ||
button == '#' || button == '\x12' || button == '\x19' ||
button == UI_REDO) {
midend_stop_anim(me);
if (!midend_redo(me))
goto done;
- *handled = true;
+ ret = PKR_SOME_EFFECT;
} else if ((button == '\x13' || button == UI_SOLVE) &&
me->ourgame->can_solve) {
- *handled = true;
+ ret = PKR_SOME_EFFECT;
if (midend_solve(me))
goto done;
} else if ((me->one_key_shortcuts && (button=='q' || button=='Q')) ||
button == '\x11' || button == UI_QUIT) {
- ret = false;
- *handled = true;
+ ret = PKR_QUIT;
goto done;
- } else
+ } else {
+ ret = PKR_UNUSED;
goto done;
+ }
} else if (movestr == MOVE_NO_EFFECT) {
+ ret = PKR_NO_EFFECT;
goto done;
} else {
- *handled = true;
+ ret = PKR_SOME_EFFECT;
if (movestr == MOVE_UI_UPDATE)
s = me->states[me->statepos-1].state;
else {
@@ -1099,12 +1101,10 @@ static bool midend_really_process_key(midend *me, int x, int y, int button,
return ret;
}
-bool midend_process_key(midend *me, int x, int y, int button, bool *handled)
+int midend_process_key(midend *me, int x, int y, int button)
{
- bool ret = true, dummy_handled;
+ int ret = PKR_UNUSED, ret2;
- if (handled == NULL) handled = &dummy_handled;
- *handled = false;
/*
* Harmonise mouse drag and release messages.
*
@@ -1206,9 +1206,10 @@ bool midend_process_key(midend *me, int x, int y, int button, bool *handled)
/*
* Fabricate a button-up for the previously pressed button.
*/
- ret = ret && midend_really_process_key
+ ret2 = midend_really_process_key
(me, x, y, (me->pressed_mouse_button +
- (LEFT_RELEASE - LEFT_BUTTON)), handled);
+ (LEFT_RELEASE - LEFT_BUTTON)));
+ ret = min(ret, ret2);
}
/* Canonicalise CTRL+ASCII. */
@@ -1243,7 +1244,8 @@ bool midend_process_key(midend *me, int x, int y, int button, bool *handled)
/*
* Now send on the event we originally received.
*/
- ret = ret && midend_really_process_key(me, x, y, button, handled);
+ ret2 = midend_really_process_key(me, x, y, button);
+ ret = min(ret, ret2);
/*
* And update the currently pressed button.
diff --git a/nestedvm.c b/nestedvm.c
index 11be3b8..0a9fdbc 100644
--- a/nestedvm.c
+++ b/nestedvm.c
@@ -206,7 +206,7 @@ int jcallback_key_event(int x, int y, int keyval)
if (fe->ox == -1)
return 1;
if (keyval >= 0 &&
- !midend_process_key(fe->me, x - fe->ox, y - fe->oy, keyval, NULL))
+ midend_process_key(fe->me, x - fe->ox, y - fe->oy, keyval) == PKR_QUIT)
return 42;
return 1;
}
@@ -323,7 +323,7 @@ static bool get_config(frontend *fe, int which)
int jcallback_newgame_event(void)
{
frontend *fe = (frontend *)_fe;
- if (!midend_process_key(fe->me, 0, 0, UI_NEWGAME, NULL))
+ if (midend_process_key(fe->me, 0, 0, UI_NEWGAME) == PKR_QUIT)
return 42;
return 0;
}
@@ -331,7 +331,7 @@ int jcallback_newgame_event(void)
int jcallback_undo_event(void)
{
frontend *fe = (frontend *)_fe;
- if (!midend_process_key(fe->me, 0, 0, UI_UNDO, NULL))
+ if (midend_process_key(fe->me, 0, 0, UI_UNDO) == PKR_QUIT)
return 42;
return 0;
}
@@ -339,7 +339,7 @@ int jcallback_undo_event(void)
int jcallback_redo_event(void)
{
frontend *fe = (frontend *)_fe;
- if (!midend_process_key(fe->me, 0, 0, UI_REDO, NULL))
+ if (midend_process_key(fe->me, 0, 0, UI_REDO) == PKR_QUIT)
return 42;
return 0;
}
@@ -347,7 +347,7 @@ int jcallback_redo_event(void)
int jcallback_quit_event(void)
{
frontend *fe = (frontend *)_fe;
- if (!midend_process_key(fe->me, 0, 0, UI_QUIT, NULL))
+ if (midend_process_key(fe->me, 0, 0, UI_QUIT) == PKR_QUIT)
return 42;
return 0;
}
diff --git a/osx.m b/osx.m
index 81d18c5..60299c9 100644
--- a/osx.m
+++ b/osx.m
@@ -767,13 +767,13 @@ struct frontend {
- (void)processButton:(int)b x:(int)x y:(int)y
{
- if (!midend_process_key(me, x, fe.h - 1 - y, b, NULL))
+ if (midend_process_key(me, x, fe.h - 1 - y, b) == PKR_QUIT)
[self close];
}
- (void)processKey:(int)b
{
- if (!midend_process_key(me, -1, -1, b, NULL))
+ if (midend_process_key(me, -1, -1, b) == PKR_QUIT)
[self close];
}
diff --git a/puzzles.h b/puzzles.h
index 25df27b..f057c21 100644
--- a/puzzles.h
+++ b/puzzles.h
@@ -320,7 +320,8 @@ void midend_reset_tilesize(midend *me);
void midend_new_game(midend *me);
void midend_restart_game(midend *me);
void midend_stop_anim(midend *me);
-bool midend_process_key(midend *me, int x, int y, int button, bool *handled);
+enum { PKR_QUIT = 0, PKR_SOME_EFFECT, PKR_NO_EFFECT, PKR_UNUSED };
+int midend_process_key(midend *me, int x, int y, int button);
key_label *midend_request_keys(midend *me, int *nkeys);
const char *midend_current_key_label(midend *me, int button);
void midend_force_redraw(midend *me);
diff --git a/windows.c b/windows.c
index 52b2ac3..5273e17 100644
--- a/windows.c
+++ b/windows.c
@@ -2678,18 +2678,18 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
cmd = wParam & ~0xF; /* low 4 bits reserved to Windows */
switch (cmd) {
case IDM_NEW:
- if (!midend_process_key(fe->me, 0, 0, UI_NEWGAME, NULL))
+ if (midend_process_key(fe->me, 0, 0, UI_NEWGAME) == PKR_QUIT)
PostQuitMessage(0);
break;
case IDM_RESTART:
midend_restart_game(fe->me);
break;
case IDM_UNDO:
- if (!midend_process_key(fe->me, 0, 0, UI_UNDO, NULL))
+ if (midend_process_key(fe->me, 0, 0, UI_UNDO) == PKR_QUIT)
PostQuitMessage(0);
break;
case IDM_REDO:
- if (!midend_process_key(fe->me, 0, 0, UI_REDO, NULL))
+ if (midend_process_key(fe->me, 0, 0, UI_REDO) == PKR_QUIT)
PostQuitMessage(0);
break;
case IDM_COPY:
@@ -2711,7 +2711,7 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
}
break;
case IDM_QUIT:
- if (!midend_process_key(fe->me, 0, 0, UI_QUIT, NULL))
+ if (midend_process_key(fe->me, 0, 0, UI_QUIT) == PKR_QUIT)
PostQuitMessage(0);
break;
case IDM_CONFIG:
@@ -2998,7 +2998,7 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
}
if (key != -1) {
- if (!midend_process_key(fe->me, 0, 0, key, NULL))
+ if (midend_process_key(fe->me, 0, 0, key) == PKR_QUIT)
PostQuitMessage(0);
} else {
MSG m;
@@ -3028,10 +3028,10 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
else
button = LEFT_BUTTON;
- if (!midend_process_key(fe->me,
- (signed short)LOWORD(lParam) - fe->bitmapPosition.left,
- (signed short)HIWORD(lParam) - fe->bitmapPosition.top,
- button, NULL))
+ if (midend_process_key(fe->me,
+ (signed short)LOWORD(lParam) - fe->bitmapPosition.left,
+ (signed short)HIWORD(lParam) - fe->bitmapPosition.top,
+ button) == PKR_QUIT)
PostQuitMessage(0);
SetCapture(hwnd);
@@ -3055,10 +3055,10 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
else
button = LEFT_RELEASE;
- if (!midend_process_key(fe->me,
- (signed short)LOWORD(lParam) - fe->bitmapPosition.left,
- (signed short)HIWORD(lParam) - fe->bitmapPosition.top,
- button, NULL))
+ if (midend_process_key(fe->me,
+ (signed short)LOWORD(lParam) - fe->bitmapPosition.left,
+ (signed short)HIWORD(lParam) - fe->bitmapPosition.top,
+ button) == PKR_QUIT)
PostQuitMessage(0);
ReleaseCapture();
@@ -3075,10 +3075,10 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
else
button = LEFT_DRAG;
- if (!midend_process_key(fe->me,
- (signed short)LOWORD(lParam) - fe->bitmapPosition.left,
- (signed short)HIWORD(lParam) - fe->bitmapPosition.top,
- button, NULL))
+ if (midend_process_key(fe->me,
+ (signed short)LOWORD(lParam) - fe->bitmapPosition.left,
+ (signed short)HIWORD(lParam) - fe->bitmapPosition.top,
+ button) == PKR_QUIT)
PostQuitMessage(0);
}
break;
@@ -3092,7 +3092,7 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
(keystate[VK_CONTROL] & 0x80))
key = UI_REDO;
}
- if (!midend_process_key(fe->me, 0, 0, key, NULL))
+ if (midend_process_key(fe->me, 0, 0, key) == PKR_QUIT)
PostQuitMessage(0);
}
return 0;