-
Notifications
You must be signed in to change notification settings - Fork 13
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
pc-tty: add PS/2 mouse support and kbd/mouse vdevs
Adds PS/2 mouse support. Because PS/2 keyboard and mouse share the same I/O port, this required some heavy refactoring of ttypc_kbd driver. It also adds /dev/kbd and /dev/mouse virtual devices, which can be used for input event capturing by applications, for instance by an X server, as part of RTOS-864. Mouse support and virtual devices are opt-in and can be enabled via board_config.h. JIRA: RTOS-896
- Loading branch information
1 parent
159684b
commit 87244ad
Showing
8 changed files
with
874 additions
and
71 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,150 @@ | ||
/* | ||
* Phoenix-RTOS | ||
* | ||
* Simple circular buffer for enqueueing PS/2 events | ||
* | ||
* Copyright 2024 Phoenix Systems | ||
* Author: Adam Greloch | ||
* | ||
* This file is part of Phoenix-RTOS. | ||
* | ||
* %LICENSE% | ||
*/ | ||
|
||
|
||
#include <errno.h> | ||
#include <stdlib.h> | ||
#include <string.h> | ||
#include <fcntl.h> | ||
#include <sys/threads.h> | ||
#include <sys/minmax.h> | ||
|
||
#include "event_queue.h" | ||
|
||
|
||
int event_queue_init(event_queue_t *eq) | ||
{ | ||
int err; | ||
|
||
if (eq == NULL) { | ||
return -EINVAL; | ||
} | ||
|
||
(void)memset(eq, 0, sizeof(event_queue_t)); | ||
|
||
err = mutexCreate(&eq->mutex); | ||
if (err < 0) { | ||
return err; | ||
} | ||
|
||
err = condCreate(&eq->waitq); | ||
if (err < 0) { | ||
resourceDestroy(eq->mutex); | ||
return err; | ||
} | ||
|
||
return EOK; | ||
} | ||
|
||
|
||
int event_queue_put(event_queue_t *eq, unsigned char event, unsigned int notify_cnt) | ||
{ | ||
if (eq == NULL) { | ||
return -EINVAL; | ||
} | ||
|
||
int bytes = 0; | ||
|
||
mutexLock(eq->mutex); | ||
if (eq->cnt < TTYPC_EQBUF_SIZE) { | ||
eq->buf[eq->w] = event; | ||
eq->w = (eq->w + 1u) % TTYPC_EQBUF_SIZE; | ||
eq->cnt++; | ||
if (eq->cnt >= notify_cnt) { | ||
condSignal(eq->waitq); | ||
} | ||
bytes = 1; | ||
} | ||
mutexUnlock(eq->mutex); | ||
|
||
return bytes; | ||
} | ||
|
||
|
||
int event_queue_get(event_queue_t *eq, void *dest, unsigned int size, unsigned int flags) | ||
{ | ||
int err; | ||
unsigned int bytes; | ||
|
||
if (eq == NULL || dest == NULL) { | ||
return -EINVAL; | ||
} | ||
|
||
if (size == 0u) { | ||
return 0; | ||
} | ||
|
||
if (size > TTYPC_EQBUF_SIZE) { | ||
size = TTYPC_EQBUF_SIZE; | ||
} | ||
|
||
mutexLock(eq->mutex); | ||
do { | ||
if ((flags & O_NONBLOCK) != 0 && eq->cnt < size) { | ||
err = -EWOULDBLOCK; | ||
break; | ||
} | ||
|
||
while (eq->cnt < size) { | ||
condWait(eq->waitq, eq->mutex, 0); | ||
} | ||
|
||
if (eq->w > eq->r) { | ||
(void)memcpy(dest, eq->buf + eq->r, bytes = size); | ||
} | ||
else { | ||
(void)memcpy(dest, eq->buf + eq->r, bytes = min(size, TTYPC_EQBUF_SIZE - eq->r)); | ||
|
||
if (bytes < size) { | ||
size -= bytes; | ||
(void)memcpy((uintptr_t *)dest + bytes, eq->buf, size); | ||
bytes += size; | ||
} | ||
} | ||
|
||
eq->r = (eq->r + bytes) % TTYPC_EQBUF_SIZE; | ||
eq->cnt -= bytes; | ||
|
||
err = bytes; | ||
} while (0); | ||
mutexUnlock(eq->mutex); | ||
|
||
return err; | ||
} | ||
|
||
|
||
int event_queue_count(event_queue_t *eq) | ||
{ | ||
int res; | ||
|
||
if (eq == NULL) { | ||
return -EINVAL; | ||
} | ||
|
||
mutexLock(eq->mutex); | ||
res = eq->cnt; | ||
mutexUnlock(eq->mutex); | ||
|
||
return res; | ||
} | ||
|
||
|
||
void event_queue_destroy(event_queue_t *eq) | ||
{ | ||
if (eq == NULL) { | ||
return; | ||
} | ||
|
||
resourceDestroy(eq->waitq); | ||
resourceDestroy(eq->mutex); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
/* | ||
* Phoenix-RTOS | ||
* | ||
* Simple circular buffer for enqueueing PS/2 events | ||
* | ||
* Copyright 2024 Phoenix Systems | ||
* Author: Adam Greloch | ||
* | ||
* This file is part of Phoenix-RTOS. | ||
* | ||
* %LICENSE% | ||
*/ | ||
|
||
|
||
#ifndef _EVENT_QUEUE_H_ | ||
#define _EVENT_QUEUE_H_ | ||
|
||
#include <sys/threads.h> | ||
|
||
#define TTYPC_EQBUF_SIZE 256u | ||
|
||
typedef struct _event_queue_t { | ||
unsigned char buf[TTYPC_EQBUF_SIZE]; | ||
unsigned int cnt; | ||
unsigned int r; | ||
unsigned int w; | ||
handle_t mutex; | ||
handle_t waitq; | ||
} event_queue_t; | ||
|
||
|
||
/* Initializes event queue */ | ||
extern int event_queue_init(event_queue_t *eq); | ||
|
||
|
||
/* Puts a byte to event queue. If the queue has notify_cnt bytes or more, wake | ||
the readers. If the queue is full, does nothing and returns 0. If event was | ||
put, returns 1. */ | ||
extern int event_queue_put(event_queue_t *eq, unsigned char event, unsigned int notify_cnt); | ||
|
||
|
||
/* Reads data from event queue */ | ||
extern int event_queue_get(event_queue_t *eq, void *dest, unsigned int size, unsigned int flags); | ||
|
||
|
||
/* Retrieves number of bytes stored in event queue */ | ||
extern int event_queue_count(event_queue_t *eq); | ||
|
||
|
||
/* Destroys event queue */ | ||
extern void event_queue_destroy(event_queue_t *eq); | ||
|
||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.