PatchworkOS
Loading...
Searching...
No Matches
kbd.c
Go to the documentation of this file.
2
4#include <kernel/fs/file.h>
5#include <kernel/fs/sysfs.h>
6#include <kernel/fs/vfs.h>
8#include <kernel/sync/lock.h>
9
10#include <errno.h>
11#include <stdio.h>
12#include <stdlib.h>
13#include <sys/io.h>
14#include <sys/math.h>
15#include <sys/proc.h>
16
18
19static atomic_uint64_t newId = ATOMIC_VAR_INIT(0);
20
22{
24
26 for (uint64_t i = 0; i < count / sizeof(kbd_event_t); i++)
27 {
29
30 if (WAIT_BLOCK_LOCK(&kbd->waitQueue, &kbd->lock, *offset != kbd->writeIndex) == ERR)
31 {
32 return i * sizeof(kbd_event_t);
33 }
34
35 ((kbd_event_t*)buffer)[i] = kbd->events[*offset];
36 *offset = (*offset + 1) % KBD_MAX_EVENT;
37 }
38
39 return count;
40}
41
43{
46 if (kbd->writeIndex != file->pos)
47 {
48 *revents |= POLLIN;
49 }
50 return &kbd->waitQueue;
51}
52
55 .poll = kbd_events_poll,
56};
57
59{
61 uint64_t nameLen = strnlen_s(kbd->name, MAX_NAME);
62 if (*offset >= nameLen)
63 {
64 return 0;
65 }
66
67 return BUFFER_READ(buffer, count, offset, kbd->name, nameLen);
68}
69
72};
73
74static void kbd_dir_cleanup(inode_t* inode)
75{
76 kbd_t* kbd = inode->private;
78 free(kbd);
79}
80
84
85kbd_t* kbd_new(const char* name)
86{
87 if (name == NULL)
88 {
89 errno = EINVAL;
90 return NULL;
91 }
92
93 if (kbdDir == NULL)
94 {
95 kbdDir = sysfs_dir_new(NULL, "kbd", NULL, NULL);
96 if (kbdDir == NULL)
97 {
98 return NULL;
99 }
100 }
101
102 kbd_t* kbd = calloc(1, sizeof(kbd_t));
103 if (kbd == NULL)
104 {
105 return NULL;
106 }
107
108 strncpy(kbd->name, name, MAX_NAME - 1);
109 kbd->name[MAX_NAME - 1] = '\0';
110 kbd->writeIndex = 0;
113 lock_init(&kbd->lock);
114
115 char id[MAX_NAME];
116 if (snprintf(id, MAX_NAME, "%llu", atomic_fetch_add(&newId, 1)) < 0)
117 {
119 free(kbd);
120 return NULL;
121 }
122
124 if (kbd->dir == NULL)
125 {
127 free(kbd);
128 return NULL;
129 }
131 if (kbd->eventsFile == NULL)
132 {
133 DEREF(kbd->dir); // kbd will be freed in kbd_dir_cleanup
134 return NULL;
135 }
136 kbd->nameFile = sysfs_file_new(kbd->dir, "name", NULL, &nameOps, kbd);
137 if (kbd->nameFile == NULL)
138 {
140 DEREF(kbd->dir);
141 return NULL;
142 }
143
144 return kbd;
145}
146
148{
149 if (kbd == NULL)
150 {
151 return;
152 }
153
154 DEREF(kbd->dir);
157 // kbd will be freed in kbd_dir_cleanup
158}
159
161{
162 if (type == KBD_PRESS)
163 {
164 kbd->mods |= mod;
165 }
166 else if (type == KBD_RELEASE)
167 {
168 kbd->mods &= ~mod;
169 }
170}
171
173{
175
176 switch (code)
177 {
178 case KBD_CAPS_LOCK:
180 break;
181 case KBD_LEFT_SHIFT:
182 case KBD_RIGHT_SHIFT:
184 break;
185 case KBD_LEFT_CTRL:
186 case KBD_RIGHT_CTRL:
188 break;
189 case KBD_LEFT_ALT:
190 case KBD_RIGHT_ALT:
192 break;
193 case KBD_LEFT_SUPER:
194 case KBD_RIGHT_SUPER:
196 break;
197 default:
198 break;
199 }
200
202 .time = timer_uptime(),
203 .code = code,
204 .mods = kbd->mods,
205 .type = type,
206 };
209}
#define MAX_NAME
Maximum length of names.
Definition MAX_NAME.h:11
#define KBD_MAX_EVENT
Maximum number of queued keyboard events.
Definition kbd.h:24
void kbd_push(kbd_t *kbd, kbd_event_type_t type, keycode_t code)
Push a keyboard event to the keyboard event queue.
Definition kbd.c:172
void kbd_free(kbd_t *kbd)
Free and deinitialize a keyboard structure.
Definition kbd.c:147
kbd_t * kbd_new(const char *name)
Allocate and initialize a keyboard structure.
Definition kbd.c:85
#define BUFFER_READ(buffer, count, offset, src, size)
Helper macros for implementing file operations dealing with simple buffers.
Definition vfs.h:372
uint64_t wait_unblock(wait_queue_t *waitQueue, uint64_t amount, errno_t err)
Unblock threads waiting on a wait queue.
Definition wait.c:168
void wait_queue_init(wait_queue_t *waitQueue)
Initialize wait queue.
Definition wait.c:71
#define WAIT_ALL
Wait for all.
Definition wait.h:26
#define WAIT_BLOCK_LOCK(waitQueue, lock, condition)
Block with a spinlock.
Definition wait.h:101
void wait_queue_deinit(wait_queue_t *waitQueue)
Deinitialize wait queue.
Definition wait.c:77
static void lock_init(lock_t *lock)
Initializes a lock.
Definition lock.h:80
#define LOCK_SCOPE(lock)
Acquires a lock for the reminder of the current scope.
Definition lock.h:57
clock_t timer_uptime(void)
Time since boot.
Definition timer.c:73
#define DEREF(ptr)
Decrement reference count.
Definition ref.h:80
#define EINVAL
Invalid argument.
Definition errno.h:142
#define errno
Error number variable.
Definition errno.h:27
#define EOK
No error.
Definition errno.h:32
poll_events_t
Poll events type.
Definition io.h:288
@ POLLIN
File descriptor is ready to read.
Definition io.h:290
keycode_t
Keyboard keycode type.
Definition kbd.h:27
kbd_mods_t
Keyboard modifiers type.
Definition kbd.h:297
kbd_event_type_t
Keyboard event type.
Definition kbd.h:286
@ KBD_RIGHT_SUPER
Right Super key.
Definition kbd.h:256
@ KBD_LEFT_ALT
Left Alt key.
Definition kbd.h:251
@ KBD_LEFT_SHIFT
Left Shift key.
Definition kbd.h:250
@ KBD_RIGHT_SHIFT
Right Shift key.
Definition kbd.h:254
@ KBD_LEFT_CTRL
Left Control key.
Definition kbd.h:249
@ KBD_RIGHT_ALT
Right Alt key.
Definition kbd.h:255
@ KBD_CAPS_LOCK
Caps Lock key.
Definition kbd.h:87
@ KBD_RIGHT_CTRL
Right Control key.
Definition kbd.h:253
@ KBD_LEFT_SUPER
Left Super key.
Definition kbd.h:252
@ KBD_MOD_SUPER
Super (Windows/Command) modifier.
Definition kbd.h:303
@ KBD_MOD_CAPS
Caps Lock modifier.
Definition kbd.h:299
@ KBD_MOD_NONE
No modifier.
Definition kbd.h:298
@ KBD_MOD_CTRL
Control modifier.
Definition kbd.h:301
@ KBD_MOD_ALT
Alt modifier.
Definition kbd.h:302
@ KBD_MOD_SHIFT
Shift modifier.
Definition kbd.h:300
@ KBD_RELEASE
Key release event.
Definition kbd.h:288
@ KBD_PRESS
Key press event.
Definition kbd.h:287
#define ROUND_DOWN(number, multiple)
Definition math.h:21
#define NULL
Pointer error value.
Definition NULL.h:23
#define ERR
Integer error value.
Definition ERR.h:17
static dentry_t * kbdDir
Definition kbd.c:17
static atomic_uint64_t newId
Definition kbd.c:19
static uint64_t kbd_name_read(file_t *file, void *buffer, uint64_t count, uint64_t *offset)
Definition kbd.c:58
static void kbd_dir_cleanup(inode_t *inode)
Definition kbd.c:74
static void kbd_update_mod(kbd_t *kbd, kbd_event_type_t type, kbd_mods_t mod)
Definition kbd.c:160
static wait_queue_t * kbd_events_poll(file_t *file, poll_events_t *revents)
Definition kbd.c:42
static file_ops_t nameOps
Definition kbd.c:70
static inode_ops_t dirInodeOps
Definition kbd.c:81
static file_ops_t eventsOps
Definition kbd.c:53
static uint64_t kbd_events_read(file_t *file, void *buffer, uint64_t count, uint64_t *offset)
Definition kbd.c:21
static dentry_t * file
Definition log_file.c:17
EFI_PHYSICAL_ADDRESS buffer
Definition mem.c:15
static atomic_long count
Definition main.c:9
static kbd_t * kbd
Definition ps2_kbd.c:10
#define ATOMIC_VAR_INIT(value)
Definition stdatomic.h:74
#define atomic_fetch_add(object, operand)
Definition stdatomic.h:283
__UINT64_TYPE__ uint64_t
Definition stdint.h:17
_PUBLIC int snprintf(char *_RESTRICT s, size_t n, const char *_RESTRICT format,...)
Definition snprintf.c:3
_PUBLIC void * calloc(size_t nmemb, size_t size)
Definition calloc.c:6
_PUBLIC void free(void *ptr)
Definition free.c:11
_PUBLIC char * strncpy(char *_RESTRICT s1, const char *_RESTRICT s2, size_t n)
Definition strncpy.c:3
size_t strnlen_s(const char *s, size_t maxsize)
Definition strnlen_s.c:4
Directory entry structure.
Definition dentry.h:83
inode_t * inode
Definition dentry.h:87
File operations structure.
Definition file.h:57
uint64_t(* read)(file_t *file, void *buffer, uint64_t count, uint64_t *offset)
Definition file.h:61
File structure.
Definition file.h:37
void(* cleanup)(inode_t *inode)
Definition inode.h:98
Inode structure.
Definition inode.h:54
void * private
Definition inode.h:66
Keyboard event structure.
Definition kbd.h:313
clock_t time
Timestamp of the event.
Definition kbd.h:314
Keyboard structure.
Definition kbd.h:31
lock_t lock
Definition kbd.h:37
dentry_t * eventsFile
Definition kbd.h:39
kbd_event_t events[KBD_MAX_EVENT]
Definition kbd.h:33
dentry_t * dir
Definition kbd.h:38
uint64_t writeIndex
Definition kbd.h:34
wait_queue_t waitQueue
Definition kbd.h:36
char name[MAX_NAME]
Definition kbd.h:32
dentry_t * nameFile
Definition kbd.h:40
kbd_mods_t mods
Definition kbd.h:35
Wait queue structure.
Definition wait.h:166
dentry_t * sysfs_dir_new(dentry_t *parent, const char *name, const inode_ops_t *inodeOps, void *private)
Create a new directory inside a mounted SysFS instance.
Definition sysfs.c:174
dentry_t * sysfs_file_new(dentry_t *parent, const char *name, const inode_ops_t *inodeOps, const file_ops_t *fileOps, void *private)
Create a new file inside a mounted SysFS instance.
Definition sysfs.c:216