1+ #include " keyboard_monitor_c.h"
2+ #include " ../keyboard_monitor.h"
3+ #include < memory>
4+
5+ // Internal structure to hold C API state
6+ struct native_keyboard_monitor_t {
7+ std::unique_ptr<nativeapi::KeyboardMonitor> cpp_monitor;
8+ std::unique_ptr<nativeapi::KeyboardEventHandler> event_handler;
9+
10+ // Store C callback functions and user data
11+ native_key_pressed_callback_t on_key_pressed;
12+ native_key_released_callback_t on_key_released;
13+ native_modifier_keys_changed_callback_t on_modifier_keys_changed;
14+ void * user_data;
15+
16+ native_keyboard_monitor_t ()
17+ : cpp_monitor(nullptr ),
18+ event_handler (nullptr ),
19+ on_key_pressed(nullptr ),
20+ on_key_released(nullptr ),
21+ on_modifier_keys_changed(nullptr ),
22+ user_data(nullptr ) {}
23+ };
24+
25+ // Helper function to convert C++ ModifierKey enum to C enum
26+ static uint32_t convert_modifier_keys_to_c (uint32_t cpp_modifier_keys) {
27+ uint32_t c_modifier_keys = 0 ;
28+
29+ if (cpp_modifier_keys & static_cast <uint32_t >(nativeapi::ModifierKey::Shift)) {
30+ c_modifier_keys |= NATIVE_MODIFIER_KEY_SHIFT;
31+ }
32+ if (cpp_modifier_keys & static_cast <uint32_t >(nativeapi::ModifierKey::Ctrl)) {
33+ c_modifier_keys |= NATIVE_MODIFIER_KEY_CTRL;
34+ }
35+ if (cpp_modifier_keys & static_cast <uint32_t >(nativeapi::ModifierKey::Alt)) {
36+ c_modifier_keys |= NATIVE_MODIFIER_KEY_ALT;
37+ }
38+ if (cpp_modifier_keys & static_cast <uint32_t >(nativeapi::ModifierKey::Meta)) {
39+ c_modifier_keys |= NATIVE_MODIFIER_KEY_META;
40+ }
41+ if (cpp_modifier_keys & static_cast <uint32_t >(nativeapi::ModifierKey::Fn)) {
42+ c_modifier_keys |= NATIVE_MODIFIER_KEY_FN;
43+ }
44+ if (cpp_modifier_keys & static_cast <uint32_t >(nativeapi::ModifierKey::CapsLock)) {
45+ c_modifier_keys |= NATIVE_MODIFIER_KEY_CAPS_LOCK;
46+ }
47+ if (cpp_modifier_keys & static_cast <uint32_t >(nativeapi::ModifierKey::NumLock)) {
48+ c_modifier_keys |= NATIVE_MODIFIER_KEY_NUM_LOCK;
49+ }
50+ if (cpp_modifier_keys & static_cast <uint32_t >(nativeapi::ModifierKey::ScrollLock)) {
51+ c_modifier_keys |= NATIVE_MODIFIER_KEY_SCROLL_LOCK;
52+ }
53+
54+ return c_modifier_keys;
55+ }
56+
57+ native_keyboard_monitor_t * native_keyboard_monitor_create (void ) {
58+ try {
59+ native_keyboard_monitor_t * monitor = new native_keyboard_monitor_t ();
60+ monitor->cpp_monitor = std::make_unique<nativeapi::KeyboardMonitor>();
61+ return monitor;
62+ } catch (...) {
63+ return nullptr ;
64+ }
65+ }
66+
67+ void native_keyboard_monitor_destroy (native_keyboard_monitor_t * monitor) {
68+ if (!monitor) {
69+ return ;
70+ }
71+
72+ // Stop monitoring first if it's active
73+ if (monitor->cpp_monitor && monitor->cpp_monitor ->IsMonitoring ()) {
74+ monitor->cpp_monitor ->Stop ();
75+ }
76+
77+ delete monitor;
78+ }
79+
80+ bool native_keyboard_monitor_set_callbacks (
81+ native_keyboard_monitor_t * monitor,
82+ native_key_pressed_callback_t on_key_pressed,
83+ native_key_released_callback_t on_key_released,
84+ native_modifier_keys_changed_callback_t on_modifier_keys_changed,
85+ void * user_data) {
86+
87+ if (!monitor || !monitor->cpp_monitor ) {
88+ return false ;
89+ }
90+
91+ // Store the C callbacks and user data
92+ monitor->on_key_pressed = on_key_pressed;
93+ monitor->on_key_released = on_key_released;
94+ monitor->on_modifier_keys_changed = on_modifier_keys_changed;
95+ monitor->user_data = user_data;
96+
97+ try {
98+ // Create C++ lambda callbacks that call the C callbacks
99+ auto key_pressed_callback = [monitor](int keycode) {
100+ if (monitor->on_key_pressed ) {
101+ monitor->on_key_pressed (keycode, monitor->user_data );
102+ }
103+ };
104+
105+ auto key_released_callback = [monitor](int keycode) {
106+ if (monitor->on_key_released ) {
107+ monitor->on_key_released (keycode, monitor->user_data );
108+ }
109+ };
110+
111+ auto modifier_keys_changed_callback = [monitor](uint32_t modifier_keys) {
112+ if (monitor->on_modifier_keys_changed ) {
113+ uint32_t c_modifier_keys = convert_modifier_keys_to_c (modifier_keys);
114+ monitor->on_modifier_keys_changed (c_modifier_keys, monitor->user_data );
115+ }
116+ };
117+
118+ // Create the event handler with the lambda callbacks
119+ monitor->event_handler = std::make_unique<nativeapi::KeyboardEventHandler>(
120+ key_pressed_callback,
121+ key_released_callback,
122+ modifier_keys_changed_callback);
123+
124+ // Set the event handler on the keyboard monitor
125+ monitor->cpp_monitor ->SetEventHandler (monitor->event_handler .get ());
126+
127+ return true ;
128+ } catch (...) {
129+ return false ;
130+ }
131+ }
132+
133+ bool native_keyboard_monitor_start (native_keyboard_monitor_t * monitor) {
134+ if (!monitor || !monitor->cpp_monitor ) {
135+ return false ;
136+ }
137+
138+ try {
139+ monitor->cpp_monitor ->Start ();
140+ return true ;
141+ } catch (...) {
142+ return false ;
143+ }
144+ }
145+
146+ bool native_keyboard_monitor_stop (native_keyboard_monitor_t * monitor) {
147+ if (!monitor || !monitor->cpp_monitor ) {
148+ return false ;
149+ }
150+
151+ try {
152+ monitor->cpp_monitor ->Stop ();
153+ return true ;
154+ } catch (...) {
155+ return false ;
156+ }
157+ }
158+
159+ bool native_keyboard_monitor_is_monitoring (const native_keyboard_monitor_t * monitor) {
160+ if (!monitor || !monitor->cpp_monitor ) {
161+ return false ;
162+ }
163+
164+ try {
165+ return monitor->cpp_monitor ->IsMonitoring ();
166+ } catch (...) {
167+ return false ;
168+ }
169+ }
0 commit comments