* consoled now opens all drivers that support the debugger mode, and runs a

thread for each of them.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@36278 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2010-04-15 08:10:13 +00:00
parent 0b807bb6ed
commit 2feb1a7f3a
+79 -45
View File
@@ -26,16 +26,24 @@
#include "Keymap.h" #include "Keymap.h"
struct console;
struct keyboard {
struct keyboard* next;
int device;
int target;
thread_id thread;
};
struct console { struct console {
int console_fd; int console_fd;
int keyboard_fd; thread_id console_writer;
int tty_master_fd; struct keyboard* keyboards;
int tty_slave_fd;
int tty_num;
thread_id keyboard_reader; int tty_master_fd;
thread_id console_writer; int tty_slave_fd;
int tty_num;
}; };
@@ -79,7 +87,7 @@ update_leds(int fd, uint32 modifiers)
static int32 static int32
keyboard_reader(void* arg) keyboard_reader(void* arg)
{ {
struct console* con = (struct console*)arg; struct keyboard* keyboard = (struct keyboard*)arg;
uint8 activeDeadKey = 0; uint8 activeDeadKey = 0;
uint32 modifiers = 0; uint32 modifiers = 0;
@@ -88,7 +96,7 @@ keyboard_reader(void* arg)
for (;;) { for (;;) {
raw_key_info rawKeyInfo; raw_key_info rawKeyInfo;
if (ioctl(con->keyboard_fd, KB_READ, &rawKeyInfo) != 0) if (ioctl(keyboard->device, KB_READ, &rawKeyInfo) != 0)
break; break;
uint32 keycode = rawKeyInfo.keycode; uint32 keycode = rawKeyInfo.keycode;
@@ -123,7 +131,7 @@ keyboard_reader(void* arg)
if (modifiers != oldModifiers) { if (modifiers != oldModifiers) {
if (isLock) if (isLock)
update_leds(con->keyboard_fd, modifiers); update_leds(keyboard->device, modifiers);
} }
} }
@@ -137,7 +145,7 @@ keyboard_reader(void* arg)
keymap.GetChars(keycode, modifiers, activeDeadKey, &string, keymap.GetChars(keycode, modifiers, activeDeadKey, &string,
&numBytes); &numBytes);
if (numBytes > 0) if (numBytes > 0)
write(con->tty_master_fd, string, numBytes); write(keyboard->target, string, numBytes);
delete[] string; delete[] string;
} }
@@ -179,17 +187,41 @@ console_writer(void* arg)
} }
/*! Opens the first keyboard driver it finds starting from the given static void
location \a start that supports the debugger extension. stop_keyboards(struct console* con)
{
// close devices
for (struct keyboard* keyboard = con->keyboards; keyboard != NULL;
keyboard = keyboard->next) {
close(keyboard->device);
}
// wait for the threads
for (struct keyboard* keyboard = con->keyboards; keyboard != NULL;) {
struct keyboard* next = keyboard->next;
wait_for_thread(keyboard->thread, NULL);
delete keyboard;
keyboard = next;
}
con->keyboards = NULL;
}
/*! Opens the all keyboard drivers it finds starting from the given
location \a start that support the debugger extension.
*/ */
static int static struct keyboard*
open_keyboard(const char* start) open_keyboards(int target, const char* start, struct keyboard* previous)
{ {
DIR* dir = opendir(start); DIR* dir = opendir(start);
if (dir == NULL) if (dir == NULL)
return -1; return NULL;
int fd = -1; struct keyboard* keyboard = previous;
while (true) { while (true) {
dirent* entry = readdir(dir); dirent* entry = readdir(dir);
@@ -206,24 +238,36 @@ open_keyboard(const char* start)
struct stat stat; struct stat stat;
if (::stat(path, &stat) != 0) if (::stat(path, &stat) != 0)
continue; continue;
if (S_ISDIR(stat.st_mode)) if (S_ISDIR(stat.st_mode))
return open_keyboard(path); return open_keyboards(target, path, previous);
// Try to open it as a device // Try to open it as a device
fd = open(path, O_RDONLY); int fd = open(path, O_RDONLY);
if (fd >= 0) { if (fd >= 0) {
// Turn on debugger mode // Turn on debugger mode
if (ioctl(fd, KB_SET_DEBUG_READER, NULL, 0) == 0) if (ioctl(fd, KB_SET_DEBUG_READER, NULL, 0) == 0) {
break; keyboard = new ::keyboard();
keyboard->device = fd;
keyboard->target = target;
keyboard->thread = spawn_thread(&keyboard_reader, path,
B_URGENT_DISPLAY_PRIORITY, keyboard);
if (keyboard->thread < 0) {
close(fd);
return NULL;
}
close(fd); if (previous != NULL)
fd = -1; previous->next = keyboard;
resume_thread(keyboard->thread);
} else
close(fd);
} }
} }
closedir(dir); closedir(dir);
return fd; return keyboard;
} }
@@ -232,20 +276,14 @@ start_console(struct console* con)
{ {
memset(con, 0, sizeof(struct console)); memset(con, 0, sizeof(struct console));
con->console_fd = -1; con->console_fd = -1;
con->keyboard_fd = -1;
con->tty_master_fd = -1; con->tty_master_fd = -1;
con->tty_slave_fd = -1; con->tty_slave_fd = -1;
con->keyboard_reader = -1;
con->console_writer = -1; con->console_writer = -1;
con->console_fd = open("/dev/console", O_WRONLY); con->console_fd = open("/dev/console", O_WRONLY);
if (con->console_fd < 0) if (con->console_fd < 0)
return -2; return -2;
con->keyboard_fd = open_keyboard("/dev/input/keyboard");
if (con->keyboard_fd < 0)
return -3;
DIR* dir = opendir("/dev/pt"); DIR* dir = opendir("/dev/pt");
if (dir != NULL) { if (dir != NULL) {
struct dirent* entry; struct dirent* entry;
@@ -294,19 +332,18 @@ start_console(struct console* con)
} }
if (con->tty_master_fd < 0 || con->tty_slave_fd < 0) if (con->tty_master_fd < 0 || con->tty_slave_fd < 0)
return -4; return -3;
con->keyboard_reader = spawn_thread(&keyboard_reader, "console reader", con->keyboards
B_URGENT_DISPLAY_PRIORITY, con); = open_keyboards(con->tty_master_fd, "/dev/input/keyboard", NULL);
if (con->keyboard_reader < 0) if (con->keyboards == NULL)
return -7; return -4;
con->console_writer = spawn_thread(&console_writer, "console writer", con->console_writer = spawn_thread(&console_writer, "console writer",
B_URGENT_DISPLAY_PRIORITY, con); B_URGENT_DISPLAY_PRIORITY, con);
if (con->console_writer < 0) if (con->console_writer < 0)
return -8; return -5;
resume_thread(con->keyboard_reader);
resume_thread(con->console_writer); resume_thread(con->console_writer);
setenv("TERM", "xterm", true); setenv("TERM", "xterm", true);
@@ -321,14 +358,11 @@ stop_console(struct console* con)
close(con->tty_master_fd); close(con->tty_master_fd);
close(con->tty_slave_fd); close(con->tty_slave_fd);
// close console and keyboard // close console and keyboards
close(con->console_fd); close(con->console_fd);
close(con->keyboard_fd); wait_for_thread(con->console_writer, NULL);
// wait for the threads stop_keyboards(con);
status_t returnCode;
wait_for_thread(con->console_writer, &returnCode);
wait_for_thread(con->keyboard_reader, &returnCode);
} }