Add an ExecDevice class to handle devices using Exec's IORequest calls. Subclass it as KeyboardDevice to use keyboard.device.

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@39108 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
François Revol 2010-10-24 01:16:36 +00:00
parent d63309cf5e
commit f2b7a266d7
5 changed files with 296 additions and 3 deletions

View File

@ -44,6 +44,35 @@ class CharHandle : public Handle {
/* block devices */
/* cf. devices.cpp */
class ExecDevice : public ConsoleNode {
public:
ExecDevice(struct IORequest *ioRequest);
ExecDevice(size_t requestSize);
ExecDevice();
virtual ~ExecDevice();
status_t AllocRequest(size_t requestSize);
status_t Open(const char *name, unsigned long unit = 0,
unsigned long flags = 0);
virtual ssize_t ReadAt(void *cookie, off_t pos, void *buffer, size_t bufferSize);
virtual ssize_t WriteAt(void *cookie, off_t pos, const void *buffer, size_t bufferSize);
virtual off_t Size() const;
struct IORequest *Request() const { return fIORequest; };
struct IOStdReq *StdRequest() const { return fIOStdReq; };
// *IO() call helpers
status_t Do(void);
protected:
struct IORequest *fIORequest;
struct IOStdReq *fIOStdReq;
};
#endif /* __cplusplus */
#endif /* HANDLE_H */

View File

@ -29,6 +29,20 @@ class ConsoleHandle : public CharHandle {
uint16 fPen;
};
class KeyboardDevice : public ExecDevice {
public:
KeyboardDevice();
virtual ~KeyboardDevice();
status_t Open();
virtual ssize_t ReadAt(void *cookie, off_t pos, void *buffer, size_t bufferSize);
virtual ssize_t WriteAt(void *cookie, off_t pos, const void *buffer, size_t bufferSize);
protected:
};
static const uint16 kPalette[] = {
0x000,
0x00a,
@ -91,6 +105,8 @@ ConsoleHandle::WriteAt(void */*cookie*/, off_t /*pos*/, const void *buffer,
//Text(&sScreen->RastPort, &string[i - len], len);
fX = 0;
fY++;
if (fY >= console_height())
fY = 0;
len = 0;
console_set_cursor(fX, fY);
continue;
@ -110,6 +126,65 @@ static ConsoleHandle sDebugOutput;
// #pragma mark -
KeyboardDevice::KeyboardDevice()
: ExecDevice()
{
}
KeyboardDevice::~KeyboardDevice()
{
}
status_t
KeyboardDevice::Open()
{
return ExecDevice::Open("keyboard.device");
}
ssize_t
KeyboardDevice::ReadAt(void *cookie, off_t pos, void *buffer, size_t bufferSize)
{
struct InputEvent event;
ssize_t actual;
do {
fIOStdReq->io_Command = KBD_READEVENT;
fIOStdReq->io_Flags = IOF_QUICK;
fIOStdReq->io_Length = sizeof(event);
fIOStdReq->io_Data = &event;
status_t err = Do();
if (err < B_OK)
return err;
} while (event.ie_Code > IECODE_UP_PREFIX);
dprintf("key: class %d sclass %d code %d qual 0x%04x\n", event.ie_Class, event.ie_SubClass,
event.ie_Code, event.ie_Qualifier);
actual = MapRawKey(&event, (char *)buffer, bufferSize, NULL);
dprintf("%s actual %d\n", __FUNCTION__, actual);
if (actual > 0) {
return actual;
}
return B_ERROR;
}
ssize_t
KeyboardDevice::WriteAt(void *cookie, off_t pos, const void *buffer, size_t bufferSize)
{
return B_ERROR;
}
static KeyboardDevice sInput;
// #pragma mark -
status_t
console_init(void)
{
@ -178,6 +253,16 @@ console_init(void)
dprintf("WBorBottom %d\n", sScreen->WBorBottom);
*/
KEYMAP_BASE_NAME = (Library *)OldOpenLibrary(KEYMAPNAME);
if (KEYMAP_BASE_NAME == NULL)
panic("Cannot open %s", KEYMAPNAME);
sInput.AllocRequest(sizeof(struct IOStdReq));
sInput.Open();
stdin = (FILE *)&sInput;
return B_OK;
}
@ -230,6 +315,9 @@ int
console_wait_for_key(void)
{
//TODO
char key;
sInput.Read(&key, 1);
dprintf("k: %02x '%c'\n", key, key);
return 0;
}

View File

@ -36,6 +36,106 @@ static uint8 gScratchBuffer[SCRATCH_SIZE];
// #pragma mark -
ExecDevice::ExecDevice(struct IORequest *ioRequest)
{
fIORequest = ioRequest;
fIOStdReq = (struct IOStdReq *)ioRequest;
}
ExecDevice::ExecDevice(size_t requestSize)
{
AllocRequest(requestSize);
}
ExecDevice::ExecDevice()
{
}
ExecDevice::~ExecDevice()
{
CloseDevice(fIORequest);
DeleteIORequest(fIORequest);
}
status_t
ExecDevice::AllocRequest(size_t requestSize)
{
struct MsgPort *inputPort = CreateMsgPort();
if (inputPort == NULL)
panic("CreateMsgPort()");
fIORequest = (struct IORequest *)CreateIORequest(inputPort, requestSize);
if (fIORequest == NULL)
panic("CreateIORequest()");
fIOStdReq = (struct IOStdReq *)fIORequest;
return B_ERROR;
}
status_t
ExecDevice::Open(const char *name, unsigned long unit, unsigned long flags)
{
status_t err;
err = exec_error(OpenDevice((uint8 *)name, unit, fIORequest, flags));
if (err < B_OK)
return err;
return B_OK;
}
ssize_t
ExecDevice::ReadAt(void *cookie, off_t pos, void *buffer, size_t bufferSize)
{
fIOStdReq->io_Command = CMD_READ;
fIOStdReq->io_Length = bufferSize;
fIOStdReq->io_Data = buffer;
fIOStdReq->io_Offset = (uint32)pos;
status_t err = Do();
if (err < B_OK)
return err;
return (ssize_t)fIOStdReq->io_Actual;
}
ssize_t
ExecDevice::WriteAt(void *cookie, off_t pos, const void *buffer, size_t bufferSize)
{
fIOStdReq->io_Command = CMD_WRITE;
fIOStdReq->io_Length = bufferSize;
fIOStdReq->io_Data = (void *)buffer;
fIOStdReq->io_Offset = (uint32)pos;
status_t err = Do();
if (err < B_OK)
return err;
return (ssize_t)fIOStdReq->io_Actual;
}
off_t
ExecDevice::Size() const
{
// ToDo: fix this!
return 1024LL * 1024 * 1024 * 1024;
// 1024 GB
}
status_t
ExecDevice::Do()
{
status_t err;
err = exec_error(DoIO(fIORequest));
return err;
}
// #pragma mark -
status_t
platform_add_boot_device(struct stage2_args *args, NodeList *devicesList)
{

View File

@ -15,7 +15,7 @@
struct GfxBase *GRAPHICS_BASE_NAME = NULL;
struct Library *KEYMAP_BASE_NAME = NULL;
/*! Maps Amiga error codes to native errors
@ -24,6 +24,8 @@ extern "C" status_t
exec_error(int32 err)
{
switch (err) {
case 0:
return B_OK;
case IOERR_OPENFAIL:
return B_DEV_BAD_DRIVE_NUM;
case IOERR_ABORTED:

View File

@ -1036,7 +1036,7 @@ struct Message {
// <exec/io.h>
/*
struct IORequest {
struct Message io_Message;
struct Device *io_Device;
@ -1058,7 +1058,7 @@ struct IOStdReq {
void *io_Data;
uint32 io_Offset;
} _PACKED;
*/
#endif /* __ASSEMBLER__ */
@ -1124,6 +1124,14 @@ extern ExecBase *EXEC_BASE_NAME;
LP1NR(0x19e, CloseLibrary, struct Library *, last, a1, \
, EXEC_BASE_NAME)
#define OpenDevice(par1, par2, par3, last) \
LP4(0x1bc, int8, OpenDevice, /*UBYTE*/uint8 *, par1, a0, unsigned long, par2, d0, struct IORequest *, par3, a1, unsigned long, last, d1, \
, EXEC_BASE_NAME)
#define CloseDevice(last) \
LP1NR(0x1c2, CloseDevice, struct IORequest *, last, a1, \
, EXEC_BASE_NAME)
#define DoIO(last) \
LP1(0x1c8, int8, DoIO, struct IORequest *, last, a1, \
, EXEC_BASE_NAME)
@ -1133,6 +1141,17 @@ extern ExecBase *EXEC_BASE_NAME;
unsigned long, last, d0, \
, EXEC_BASE_NAME)
#define CreateIORequest(par1, last) \
LP2(0x28e, APTR, CreateIORequest, struct MsgPort *, par1, a0, unsigned long, last, d0, \
, EXEC_BASE_NAME)
#define DeleteIORequest(last) \
LP1NR(0x294, DeleteIORequest, APTR, last, a0, \
, EXEC_BASE_NAME)
#define CreateMsgPort() \
LP0(0x29a, struct MsgPort *, CreateMsgPort, \
, EXEC_BASE_NAME)
@ -1315,6 +1334,61 @@ extern struct Library *INTUITION_BASE_NAME;
#endif /* __ASSEMBLER__ */
// <devices/keymap.h>
#ifndef KEYMAP_BASE_NAME
#define KEYMAP_BASE_NAME KeymapBase
#endif
#define KEYMAPNAME "keymap.library"
#ifndef __ASSEMBLER__
#define MapRawKey(par1, par2, par3, last) \
LP4(0x2a, int16, MapRawKey, struct InputEvent *, par1, a0, char *, par2, a1, long, par3, d1, struct KeyMap *, last, a2, \
, KEYMAP_BASE_NAME)
extern struct Library *KEYMAP_BASE_NAME;
#endif /* __ASSEMBLER__ */
// <devices/keyboard.h>
#define KBD_READEVENT (CMD_NONSTD+0)
// <devices/inputevent.h>
#ifndef __ASSEMBLER__
struct InputEvent {
struct InputEvent *ie_NextEvent;
uint8 ie_Class;
uint8 ie_SubClass;
uint16 ie_Code;
uint16 ie_Qualifier;
union {
struct {
int16 ie_x;
int16 ie_y;
} ie_xy;
APTR ie_addr;
struct {
uint8 ie_prev1DownCode;
uint8 ie_prev1DownQual;
uint8 ie_prev2DownCode;
uint8 ie_prev2DownQual;
} ie_dead;
} ie_position;
/*struct timeval*/
struct { uint32 tv_secs, tv_micro; } ie_TimeStamp;
};
#endif /* __ASSEMBLER__ */
#define IECLASS_RAWKEY 0x01
#define IESUBCLASS_RAWKEY 0x01
#define IECODE_UP_PREFIX 0x80
#ifdef __cplusplus
}
#endif