File: html5_event_callback_in_two_threads.c

package info (click to toggle)
emscripten 3.1.6~dfsg-5
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 114,112 kB
  • sloc: ansic: 583,052; cpp: 391,943; javascript: 79,361; python: 54,180; sh: 49,997; pascal: 4,658; makefile: 3,426; asm: 2,191; lisp: 1,869; ruby: 488; cs: 142
file content (116 lines) | stat: -rw-r--r-- 5,204 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
#include <emscripten.h>
#include <emscripten/html5.h>
#include <emscripten/threading.h>
#include <emscripten/key_codes.h>
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <assert.h>

void *application_main_thread_id = 0;
void *main_browser_thread_id = 0;

volatile int saw_keydown_event_on_enter_key_on_application_main_thread = 0;
volatile int saw_keydown_event_on_enter_key_on_main_browser_thread = 0;
volatile int saw_keypress_event_on_enter_key = 0;

void ReportResult(int code)
{
  printf("Test finished with code: %d\n", code);
#ifdef REPORT_RESULT
  REPORT_RESULT(code);
#endif
  exit(code);
}

EM_BOOL keydown_callback_on_application_main_thread(int eventType, const EmscriptenKeyboardEvent *e, void *userData)
{
  int dom_pk_code = emscripten_compute_dom_pk_code(e->code);
  printf("keydown_callback_on_application_main_thread received on pthread: %p, application_main_thread_id: %p, dom_pk_code: %s\n", (void*)pthread_self(), application_main_thread_id, emscripten_dom_pk_code_to_string(dom_pk_code));
  assert((void*)pthread_self() == application_main_thread_id);

  if (dom_pk_code == DOM_PK_ENTER) saw_keydown_event_on_enter_key_on_application_main_thread = 1;
  return 0;
}

EM_BOOL keydown_callback_on_main_browser_thread(int eventType, const EmscriptenKeyboardEvent *e, void *userData)
{
  int dom_pk_code = emscripten_compute_dom_pk_code(e->code);
  printf("keydown_callback_on_main_browser_thread received on pthread: %p, main_browser_thread_id; %p, dom_pk_code: %s\n", (void*)pthread_self(), main_browser_thread_id, emscripten_dom_pk_code_to_string(dom_pk_code));
  assert((void*)pthread_self() == main_browser_thread_id);

#if __EMSCRIPTEN_PTHREADS__
  EmscriptenKeyboardEvent *duplicatedEventStruct = malloc(sizeof(*e));
  memcpy(duplicatedEventStruct, e, sizeof(*e));
  emscripten_dispatch_to_thread(application_main_thread_id, EM_FUNC_SIG_IIII, keydown_callback_on_application_main_thread, duplicatedEventStruct, eventType, duplicatedEventStruct, userData);
#else
  keydown_callback_on_application_main_thread(eventType, e, userData);
#endif

  if (dom_pk_code == DOM_PK_ENTER) saw_keydown_event_on_enter_key_on_main_browser_thread = 1;

  return dom_pk_code == DOM_PK_ENTER; // Suppress default event handling for the enter/return key so that it should not generate the keypress event.
}


EM_BOOL keypress_callback_on_application_main_thread(int eventType, const EmscriptenKeyboardEvent *e, void *userData)
{
  int dom_pk_code = emscripten_compute_dom_pk_code(e->code);
  printf("keypress_callback_on_application_main_thread received on pthread: %p, application_main_thread_id; %p, dom_pk_code: %s\n", (void*)pthread_self(), application_main_thread_id, emscripten_dom_pk_code_to_string(dom_pk_code));
  assert((void*)pthread_self() == application_main_thread_id);

  if (dom_pk_code == DOM_PK_ENTER)
  {
    saw_keypress_event_on_enter_key = 1;
    printf("Test failed! KeyPress event came through even though it was suppressed in KeyDown handler!\n");
    ReportResult(12345); // FAIL
  }
  return 0;
}

EM_BOOL keyup_callback_on_application_main_thread(int eventType, const EmscriptenKeyboardEvent *e, void *userData)
{
  int dom_pk_code = emscripten_compute_dom_pk_code(e->code);
  printf("keyup_callback_on_application_main_thread received on pthread: %p, application_main_thread_id; %p, dom_pk_code: %s\n", (void*)pthread_self(), application_main_thread_id, emscripten_dom_pk_code_to_string(dom_pk_code));
  assert((void*)pthread_self() == application_main_thread_id);

  if (dom_pk_code == DOM_PK_ENTER)
  {
    if (!saw_keydown_event_on_enter_key_on_application_main_thread)
    {
      printf("Test failed! KeyUp event came through, but a KeyDown event should have first been processed on the application main thread!\n");
      ReportResult(12346); // FAIL
    }
    if (!saw_keydown_event_on_enter_key_on_main_browser_thread)
    {
      printf("Test failed! KeyUp event came through, but a KeyDown event should have first been processed on the main browser thread!\n");
      ReportResult(12347); // FAIL      
    }
    if (saw_keypress_event_on_enter_key)
    {
      printf("Test failed! KeyUp event came through, but a KeyPress event was first seen, suppressing it did not work!\n");
      ReportResult(12348); // FAIL
    }
    printf("Test passed!\n");
    ReportResult(1); // PASS
  }
  return 0;
}

int main()
{
  main_browser_thread_id = emscripten_main_browser_thread_id();
  assert(main_browser_thread_id);
  application_main_thread_id = (void*)pthread_self();
  assert(application_main_thread_id);

  printf("Main browser thread ID: %p, application main thread ID: %p\n", main_browser_thread_id, application_main_thread_id);

  emscripten_set_keydown_callback_on_thread(0, 0, 1, keydown_callback_on_main_browser_thread, EM_CALLBACK_THREAD_CONTEXT_MAIN_BROWSER_THREAD);
  emscripten_set_keypress_callback_on_thread(0, 0, 1, keypress_callback_on_application_main_thread, EM_CALLBACK_THREAD_CONTEXT_CALLING_THREAD);
  emscripten_set_keyup_callback_on_thread(0, 0, 1, keyup_callback_on_application_main_thread, EM_CALLBACK_THREAD_CONTEXT_CALLING_THREAD);

  printf("Please press the Enter key.\n");

  emscripten_exit_with_live_runtime();
}