+ if (screenhack_event_helper (mi->dpy, mi->window, event)) {
+ /* If a clear is in progress, don't interrupt or restart it. */
+ if (mi->needs_clear)
+ mi->xlmft->got_init &= ~(1ul << mi->screen_number);
+ else
+ mi->xlmft->hack_init (mi);
+ return True;
+ }
+ }
+ return False;
+}
+
+void
+xlockmore_do_fps (Display *dpy, Window w, fps_state *fpst, void *closure)
+{
+ ModeInfo *mi = (ModeInfo *) closure;
+ fps_compute (fpst, 0, mi ? mi->recursion_depth : -1);
+ fps_draw (fpst);
+}
+
+
+static void
+xlockmore_free (Display *dpy, Window window, void *closure)
+{
+ ModeInfo *mi = (ModeInfo *) closure;
+
+ if (mi->eraser)
+ eraser_free (mi->eraser);
+
+ /* Some hacks may need to do things with their Display * on cleanup. And
+ under JWXYZ, the Display * for this hack gets cleaned up right after
+ xlockmore_free returns. Thus, hack_free has to happen now, rather than
+ after the final screen has been released.
+ */
+ if (mi->xlmft->hack_free)
+ mi->xlmft->hack_free (mi);
+
+ /* Find us in live_displays and clear that slot. */
+ assert (mi->xlmft->live_displays & (1ul << mi->screen_number));
+ mi->xlmft->live_displays &= ~(1ul << mi->screen_number);
+ if (!mi->xlmft->live_displays)
+ xlockmore_release_screens (mi);
+
+ XFreeGC (dpy, mi->gc);
+ free_colors (mi->xgwa.screen, mi->xgwa.colormap, mi->colors, mi->npixels);
+ free (mi->colors);
+ free (mi->pixels);
+
+ free (mi);
+}
+
+
+void
+xlockmore_mi_init (ModeInfo *mi, size_t state_size, void **state_array)
+{
+ struct xlockmore_function_table *xlmft = mi->xlmft;
+
+ /* Steal the state_array for safe keeping.
+ Only necessary when the screenhack isn't a once per process deal.
+ (i.e. macOS, iOS, Android)
+ */
+ assert ((!xlmft->state_array && !*state_array) ||
+ xlmft->state_array == state_array);
+ xlmft->state_array = state_array;
+
+ if (!*xlmft->state_array) {
+ *xlmft->state_array = calloc (XLOCKMORE_NUM_SCREENS, state_size);
+
+ if (!*xlmft->state_array) {
+#ifdef HAVE_JWXYZ
+ /* Throws an exception instead of exiting the process. */
+ jwxyz_abort ("%s: out of memory", progname);
+#else
+ fprintf (stderr, "%s: out of memory\n", progname);
+ exit (1);
+#endif
+ }
+ }
+
+ /* Find the appropriate state object, clear it, and we're done. */
+ {
+ if (xlmft->hack_free)
+ xlmft->hack_free (mi);
+ memset ((char *)(*xlmft->state_array) + mi->screen_number * state_size, 0,
+ state_size);
+ }
+}
+
+
+Bool
+xlockmore_no_events (ModeInfo *mi, XEvent *event)
+{
+ return False;