+
+void
+xlockmore_mi_init (ModeInfo *mi, size_t state_size, void **state_array,
+ void (*hack_free_state) (ModeInfo *))
+{
+ 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;
+ assert (!xlmft->state_size || xlmft->state_size == state_size);
+ xlmft->state_size = state_size;
+ assert (!xlmft->hack_free_state ||
+ xlmft->hack_free_state == hack_free_state);
+ xlmft->hack_free_state = hack_free_state;
+
+ 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_state)
+ xlmft->hack_free_state (mi);
+ memset ((char *)(*xlmft->state_array) + mi->screen_number * state_size, 0,
+ state_size);
+ }
+}