@ 261106.15
current
/*
 * Copyright 2026 The Emscripten Authors.  All rights reserved.
 * Emscripten is available under two separate licenses, the MIT license and the
 * University of Illinois/NCSA Open Source License.  Both these licenses can be
 * found in the LICENSE file.
 */

#include <assert.h>
#include <emscripten.h>
#include <emscripten/html5.h>
#include <emscripten/threading.h>
#include <pthread.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef bool (*event_callback)(int event_type, void *event_data, void *user_data);
extern void _emscripten_run_callback_on_thread(pthread_t t,
                                               event_callback f,
                                               int event_type,
                                               void *event_data,
                                               size_t event_data_size,
                                               void *user_data);

bool on_wheel(int event_type, void *event_data, void *user_data) {
  const EmscriptenWheelEvent *e = (const EmscriptenWheelEvent *)event_data;
  // Test that the event_data contents are properly aligned.  These accesses
  // will fail under SAFE_HEAP if they are not.
  assert(e->deltaX == 1.0);
  assert(e->deltaY == 2.0);
  assert(e->deltaZ == 3.0);
  printf("done\n");
  emscripten_force_exit(0);
  return true;
}

void *sender(void *arg) {
  pthread_t target = (pthread_t)arg;
  EmscriptenWheelEvent ev;
  memset(&ev, 0, sizeof(ev));
  ev.deltaX = 1.0;
  ev.deltaY = 2.0;
  ev.deltaZ = 3.0;
  _emscripten_run_callback_on_thread(target, on_wheel, EMSCRIPTEN_EVENT_WHEEL,
                                     &ev, sizeof(ev), NULL);
  return NULL;
}

void dummy(void) {}

int main(void) {
  pthread_t t;
  pthread_create(&t, NULL, sender, (void *)pthread_self());
  emscripten_set_main_loop(dummy, 1, 0);
}