Skip to content

Commit 1a33617

Browse files
Merge pull request #21 from dreamer-coding/add_device
Add new devices
2 parents 187023c + 55fb225 commit 1a33617

File tree

10 files changed

+1011
-466
lines changed

10 files changed

+1011
-466
lines changed

code/logic/device.c

Lines changed: 350 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,350 @@
1+
/*
2+
* -----------------------------------------------------------------------------
3+
* Project: Fossil Logic
4+
*
5+
* This file is part of the Fossil Logic project, which aims to develop high-
6+
* performance, cross-platform applications and libraries. The code contained
7+
* herein is subject to the terms and conditions defined in the project license.
8+
*
9+
* Author: Michael Gene Brockus (Dreamer)
10+
*
11+
* Copyright (C) 2024 Fossil Logic. All rights reserved.
12+
* -----------------------------------------------------------------------------
13+
*/
14+
#include "fossil/io/device.h"
15+
#include <stdio.h>
16+
#include <stdlib.h>
17+
#include <string.h>
18+
19+
#if defined(_WIN32) || defined(_WIN64)
20+
#include <conio.h>
21+
#include <windows.h>
22+
#else
23+
#include <termios.h>
24+
#include <unistd.h>
25+
#include <fcntl.h>
26+
#include <sys/select.h> // For fd_set, FD_ZERO, FD_SET, select
27+
#include <sys/time.h> // For struct timeval
28+
#include <sys/types.h> // For system types
29+
#endif
30+
31+
#define MAX_KEYBINDS 256
32+
#define MAX_TOUCHBINDS 256
33+
#define MAX_MOUSEBINDS 256
34+
35+
typedef struct {
36+
fossil_io_mouse_event_t event;
37+
fossil_io_mouse_callback_t callback;
38+
} fossil_io_mouse_binding_t;
39+
40+
typedef struct {
41+
fossil_io_mouse_binding_t bindings[MAX_MOUSEBINDS];
42+
size_t count;
43+
} fossil_io_mouse_manager_t;
44+
45+
typedef struct {
46+
fossil_io_touch_event_t event;
47+
fossil_io_touch_callback_t callback;
48+
} fossil_io_touch_binding_t;
49+
50+
typedef struct {
51+
fossil_io_touch_binding_t bindings[MAX_TOUCHBINDS];
52+
size_t count;
53+
} fossil_io_touch_manager_t;
54+
55+
typedef struct {
56+
fossil_io_keyboard_event_t event;
57+
fossil_io_keyboard_callback_t callback;
58+
} fossil_io_keyboard_binding_t;
59+
60+
typedef struct {
61+
fossil_io_keyboard_binding_t bindings[MAX_KEYBINDS];
62+
size_t count;
63+
} fossil_io_keyboard_manager_t;
64+
65+
static fossil_io_keyboard_manager_t keyboard_manager;
66+
static fossil_io_touch_manager_t touch_manager;
67+
static fossil_io_mouse_manager_t mouse_manager;
68+
69+
70+
#if defined(_WIN32) || defined(_WIN64)
71+
72+
static int fossil_io_keyboard_is_key_pressed(void) {
73+
return _kbhit();
74+
}
75+
76+
static fossil_io_keyboard_event_t fossil_io_keyboard_get_event(void) {
77+
fossil_io_keyboard_event_t event = {0};
78+
int key = _getch();
79+
80+
// Check for extended keys (e.g., arrow keys, function keys)
81+
if (key == 0 || key == 224) {
82+
key = _getch(); // Fetch the actual key code
83+
}
84+
85+
// Check modifiers
86+
event.shift = GetKeyState(VK_SHIFT) & 0x8000;
87+
event.ctrl = GetKeyState(VK_CONTROL) & 0x8000;
88+
event.alt = GetKeyState(VK_MENU) & 0x8000;
89+
event.key = (char)key;
90+
91+
return event;
92+
}
93+
94+
#else
95+
static struct termios old_termios, new_termios;
96+
97+
static void fossil_io_keyboard_enable_raw_mode(void) {
98+
tcgetattr(STDIN_FILENO, &old_termios);
99+
new_termios = old_termios;
100+
new_termios.c_lflag &= ~(ICANON | ECHO);
101+
tcsetattr(STDIN_FILENO, TCSANOW, &new_termios);
102+
}
103+
104+
static void fossil_io_keyboard_disable_raw_mode(void) {
105+
tcsetattr(STDIN_FILENO, TCSANOW, &old_termios);
106+
}
107+
108+
static int fossil_io_keyboard_is_key_pressed(void) {
109+
struct timeval timeout = {0L, 0L};
110+
fd_set fds;
111+
FD_ZERO(&fds);
112+
FD_SET(STDIN_FILENO, &fds);
113+
return select(STDIN_FILENO + 1, &fds, NULL, NULL, &timeout) > 0;
114+
}
115+
116+
static fossil_io_keyboard_event_t fossil_io_keyboard_get_event(void) {
117+
fossil_io_keyboard_event_t event = {0};
118+
char c;
119+
read(STDIN_FILENO, &c, 1);
120+
121+
event.key = c;
122+
123+
// Modifier keys (POSIX doesn't have direct access to key states; approximation)
124+
if (c == 27) { // Alt key (ESC sequence)
125+
event.alt = 1;
126+
read(STDIN_FILENO, &c, 1);
127+
event.key = c;
128+
} else if (c < 32) { // Ctrl key (control characters)
129+
event.ctrl = 1;
130+
event.key = c + 96; // Map to lowercase ASCII
131+
} else if (c == 127) { // Backspace key with Ctrl
132+
event.ctrl = 1;
133+
event.key = 8;
134+
}
135+
136+
return event;
137+
}
138+
#endif
139+
140+
void fossil_io_keyboard_init(void) {
141+
memset(&keyboard_manager, 0, sizeof(keyboard_manager));
142+
printf("[mouse] Initialized: bindings cleared\n");
143+
#if defined(_WIN32) || defined(_WIN64)
144+
// Windows doesn't require explicit setup for raw mode.
145+
#else
146+
fossil_io_keyboard_enable_raw_mode();
147+
atexit(fossil_io_keyboard_disable_raw_mode);
148+
#endif
149+
}
150+
151+
void fossil_io_keyboard_shutdown(void) {
152+
memset(&keyboard_manager, 0, sizeof(keyboard_manager));
153+
printf("[mouse] Shutdown: bindings released\n");
154+
#if defined(_WIN32) || defined(_WIN64)
155+
// Windows doesn't require explicit cleanup for raw mode.
156+
#else
157+
fossil_io_keyboard_disable_raw_mode();
158+
#endif
159+
}
160+
161+
void fossil_io_keyboard_clear_bindings(void) {
162+
keyboard_manager.count = 0;
163+
}
164+
165+
void fossil_io_keyboard_register_binding(fossil_io_keyboard_event_t event, fossil_io_keyboard_callback_t callback) {
166+
if (keyboard_manager.count < MAX_KEYBINDS) {
167+
keyboard_manager.bindings[keyboard_manager.count].event = event;
168+
keyboard_manager.bindings[keyboard_manager.count].callback = callback;
169+
keyboard_manager.count++;
170+
} else {
171+
fprintf(stderr, "Max keybindings reached.\n");
172+
}
173+
}
174+
175+
void fossil_io_keyboard_unregister_binding(fossil_io_keyboard_event_t event) {
176+
for (size_t i = 0; i < keyboard_manager.count; ++i) {
177+
if (keyboard_manager.bindings[i].event.key == event.key &&
178+
keyboard_manager.bindings[i].event.shift == event.shift &&
179+
keyboard_manager.bindings[i].event.ctrl == event.ctrl &&
180+
keyboard_manager.bindings[i].event.alt == event.alt) {
181+
for (size_t j = i; j < keyboard_manager.count - 1; ++j) {
182+
keyboard_manager.bindings[j] = keyboard_manager.bindings[j + 1];
183+
}
184+
keyboard_manager.count--;
185+
return;
186+
}
187+
}
188+
fprintf(stderr, "No matching keybinding to unregister.\n");
189+
}
190+
191+
void fossil_io_keyboard_poll_events(void) {
192+
if (fossil_io_keyboard_is_key_pressed()) {
193+
fossil_io_keyboard_event_t event = fossil_io_keyboard_get_event();
194+
195+
for (size_t i = 0; i < keyboard_manager.count; ++i) {
196+
fossil_io_keyboard_binding_t *binding = &keyboard_manager.bindings[i];
197+
if (binding->event.key == event.key &&
198+
binding->event.shift == event.shift &&
199+
binding->event.ctrl == event.ctrl &&
200+
binding->event.alt == event.alt) {
201+
if (binding->callback) {
202+
binding->callback(event);
203+
}
204+
break;
205+
}
206+
}
207+
}
208+
}
209+
210+
// MOUSE
211+
static int fossil_io_mouse_event_match(const fossil_io_mouse_event_t* a, const fossil_io_mouse_event_t* b) {
212+
return (a->button == b->button &&
213+
(a->shift == b->shift || a->shift == -1 || b->shift == -1) &&
214+
(a->ctrl == b->ctrl || a->ctrl == -1 || b->ctrl == -1) &&
215+
(a->alt == b->alt || a->alt == -1 || b->alt == -1));
216+
}
217+
218+
// Dummy OS-agnostic implementation for now
219+
static void fossil_io_mouse_get_event(fossil_io_mouse_event_t* event) {
220+
static int toggle = 0;
221+
event->x = 100 + (toggle++ % 10);
222+
event->y = 200 + (toggle % 5);
223+
event->button = toggle % 2;
224+
event->shift = -1;
225+
event->ctrl = -1;
226+
event->alt = -1;
227+
}
228+
229+
void fossil_io_mouse_register_binding(fossil_io_mouse_event_t event, fossil_io_mouse_callback_t callback) {
230+
if (mouse_manager.count >= MAX_MOUSEBINDS) {
231+
fprintf(stderr, "[mouse] Max bindings reached\n");
232+
return;
233+
}
234+
235+
mouse_manager.bindings[mouse_manager.count++] = (fossil_io_mouse_binding_t){ event, callback };
236+
}
237+
238+
void fossil_io_mouse_unregister_binding(fossil_io_mouse_event_t event) {
239+
for (size_t i = 0; i < mouse_manager.count; ++i) {
240+
if (fossil_io_mouse_event_match(&mouse_manager.bindings[i].event, &event)) {
241+
memmove(&mouse_manager.bindings[i], &mouse_manager.bindings[i + 1],
242+
sizeof(fossil_io_mouse_binding_t) * (mouse_manager.count - i - 1));
243+
--mouse_manager.count;
244+
return;
245+
}
246+
}
247+
fprintf(stderr, "[mouse] Binding not found\n");
248+
}
249+
250+
void fossil_io_mouse_poll_events(void) {
251+
fossil_io_mouse_event_t event = {0};
252+
fossil_io_mouse_get_event(&event);
253+
254+
for (size_t i = 0; i < mouse_manager.count; ++i) {
255+
if (fossil_io_mouse_event_match(&mouse_manager.bindings[i].event, &event)) {
256+
if (mouse_manager.bindings[i].callback) {
257+
mouse_manager.bindings[i].callback(event);
258+
}
259+
}
260+
}
261+
}
262+
263+
void fossil_io_mouse_clear_bindings(void) {
264+
mouse_manager.count = 0;
265+
for (size_t i = 0; i < MAX_MOUSEBINDS; ++i) {
266+
mouse_manager.bindings[i].callback = NULL;
267+
}
268+
}
269+
270+
void fossil_io_mouse_init(void) {
271+
memset(&mouse_manager, 0, sizeof(mouse_manager));
272+
printf("[mouse] Initialized: bindings cleared\n");
273+
}
274+
275+
void fossil_io_mouse_shutdown(void) {
276+
memset(&mouse_manager, 0, sizeof(mouse_manager));
277+
printf("[mouse] Shutdown: bindings released\n");
278+
}
279+
280+
// TOUCH
281+
static int fossil_io_touch_event_match(const fossil_io_touch_event_t* a, const fossil_io_touch_event_t* b) {
282+
return (a->touch_id == b->touch_id &&
283+
a->action == b->action &&
284+
(a->shift == b->shift || a->shift == -1 || b->shift == -1) &&
285+
(a->ctrl == b->ctrl || a->ctrl == -1 || b->ctrl == -1) &&
286+
(a->alt == b->alt || a->alt == -1 || b->alt == -1));
287+
}
288+
289+
// Dummy implementation for simulation/testing
290+
static void fossil_io_touch_get_event(fossil_io_touch_event_t* event) {
291+
static int state = 0;
292+
event->x = 320 + (state % 3);
293+
event->y = 240 + (state % 2);
294+
event->touch_id = 1;
295+
event->action = state++ % 3; // 0=start, 1=move, 2=end
296+
event->shift = -1;
297+
event->ctrl = -1;
298+
event->alt = -1;
299+
}
300+
301+
void fossil_io_touch_register_binding(fossil_io_touch_event_t event, fossil_io_touch_callback_t callback) {
302+
if (touch_manager.count >= MAX_TOUCHBINDS) {
303+
fprintf(stderr, "[touch] Max bindings reached\n");
304+
return;
305+
}
306+
307+
touch_manager.bindings[touch_manager.count++] = (fossil_io_touch_binding_t){ event, callback };
308+
}
309+
310+
void fossil_io_touch_unregister_binding(fossil_io_touch_event_t event) {
311+
for (size_t i = 0; i < touch_manager.count; ++i) {
312+
if (fossil_io_touch_event_match(&touch_manager.bindings[i].event, &event)) {
313+
memmove(&touch_manager.bindings[i], &touch_manager.bindings[i + 1],
314+
sizeof(fossil_io_touch_binding_t) * (touch_manager.count - i - 1));
315+
--touch_manager.count;
316+
return;
317+
}
318+
}
319+
fprintf(stderr, "[touch] Binding not found\n");
320+
}
321+
322+
void fossil_io_touch_poll_events(void) {
323+
fossil_io_touch_event_t event = {0};
324+
fossil_io_touch_get_event(&event);
325+
326+
for (size_t i = 0; i < touch_manager.count; ++i) {
327+
if (fossil_io_touch_event_match(&touch_manager.bindings[i].event, &event)) {
328+
if (touch_manager.bindings[i].callback) {
329+
touch_manager.bindings[i].callback(event);
330+
}
331+
}
332+
}
333+
}
334+
335+
void fossil_io_touch_clear_bindings(void) {
336+
touch_manager.count = 0;
337+
for (size_t i = 0; i < MAX_TOUCHBINDS; ++i) {
338+
touch_manager.bindings[i].callback = NULL;
339+
}
340+
}
341+
342+
void fossil_io_touch_init(void) {
343+
memset(&touch_manager, 0, sizeof(touch_manager));
344+
printf("[touch] Initialized: bindings cleared\n");
345+
}
346+
347+
void fossil_io_touch_shutdown(void) {
348+
memset(&touch_manager, 0, sizeof(touch_manager));
349+
printf("[touch] Shutdown: bindings released\n");
350+
}

0 commit comments

Comments
 (0)