Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev 4570 → Rev 4571

/trunk/uspace/srv/console/console.c
51,7 → 51,6
#include <sysinfo.h>
#include <event.h>
#include <devmap.h>
#include <assert.h>
#include <fibril_sync.h>
 
#include "console.h"
99,68 → 98,9
size_t cnt; /**< Width of the span. */
} fb_pending;
 
/** Pending input structure. */
typedef struct {
link_t link;
console_t *cons; /**< Console waiting for input */
ipc_callid_t rid; /**< Call ID waiting for input */
ipc_callid_t callid; /**< Call ID waiting for IPC_DATA_READ */
size_t pos; /**< Position of the last stored data */
size_t size; /**< Size of ther buffer */
char *data; /**< Already stored data */
} pending_input_t;
 
LIST_INITIALIZE(pending_input);
 
static FIBRIL_MUTEX_INITIALIZE(input_mutex);
static FIBRIL_CONDVAR_INITIALIZE(input_cv);
static input_flag = false;
 
/** Process pending input requests */
static void process_pending_input(void)
{
link_t *cur;
loop:
fibril_mutex_lock(&input_mutex);
while (!input_flag)
fibril_condvar_wait(&input_cv, &input_mutex);
rescan:
for (cur = pending_input.next; cur != &pending_input; cur = cur->next) {
pending_input_t *pr = list_get_instance(cur, pending_input_t, link);
console_event_t ev;
if (keybuffer_pop(&pr->cons->keybuffer, &ev)) {
if (pr->data != NULL) {
if (ev.type == KEY_PRESS) {
pr->data[pr->pos] = ev.c;
pr->pos++;
}
} else {
ipc_answer_4(pr->rid, EOK, ev.type, ev.key, ev.mods, ev.c);
list_remove(cur);
free(pr);
goto rescan;
}
}
if ((pr->data != NULL) && (pr->pos == pr->size)) {
(void) ipc_data_read_finalize(pr->callid, pr->data, pr->size);
ipc_answer_1(pr->rid, EOK, pr->size);
 
free(pr->data);
list_remove(cur);
free(pr);
goto rescan;
}
}
input_flag = false;
fibril_mutex_unlock(&input_mutex);
goto loop;
}
 
static void curs_visibility(bool visible)
{
async_msg_1(fb_info.phone, FB_CURSOR_VISIBILITY, visible);
461,8 → 401,7
fibril_mutex_lock(&input_mutex);
keybuffer_push(&active_console->keybuffer, &ev);
input_flag = true;
fibril_condvar_signal(&input_cv);
fibril_condvar_broadcast(&input_cv);
fibril_mutex_unlock(&input_mutex);
break;
default:
527,6 → 466,7
size_t pos = 0;
console_event_t ev;
fibril_mutex_lock(&input_mutex);
recheck:
while ((keybuffer_pop(&cons->keybuffer, &ev)) && (pos < size)) {
if (ev.type == KEY_PRESS) {
buf[pos] = ev.c;
539,22 → 479,8
ipc_answer_1(rid, EOK, size);
free(buf);
} else {
pending_input_t *pr = (pending_input_t *) malloc(sizeof(pending_input_t));
if (!pr) {
fibril_mutex_unlock(&input_mutex);
ipc_answer_0(callid, ENOMEM);
ipc_answer_0(rid, ENOMEM);
free(buf);
return;
}
pr->cons = cons;
pr->rid = rid;
pr->callid = callid;
pr->pos = pos;
pr->size = size;
pr->data = buf;
list_append(&pr->link, &pending_input);
fibril_condvar_wait(&input_cv, &input_mutex);
goto recheck;
}
fibril_mutex_unlock(&input_mutex);
}
564,21 → 490,12
console_event_t ev;
 
fibril_mutex_lock(&input_mutex);
recheck:
if (keybuffer_pop(&cons->keybuffer, &ev)) {
ipc_answer_4(rid, EOK, ev.type, ev.key, ev.mods, ev.c);
} else {
pending_input_t *pr = (pending_input_t *) malloc(sizeof(pending_input_t));
if (!pr) {
fibril_mutex_unlock(&input_mutex);
ipc_answer_0(rid, ENOMEM);
return;
}
pr->cons = cons;
pr->rid = rid;
pr->callid = 0;
pr->data = NULL;
list_append(&pr->link, &pending_input);
fibril_condvar_wait(&input_cv, &input_mutex);
goto recheck;
}
fibril_mutex_unlock(&input_mutex);
}
737,14 → 654,6
async_new_connection(phonehash, 0, NULL, keyboard_events);
 
fid_t fid = fibril_create(process_pending_input, NULL);
if (!fid) {
printf(NAME ": Failed to create fibril for handling pending "
"input\n");
return -1;
}
fibril_add_ready(fid);
/* Connect to framebuffer driver */
fb_info.phone = ipc_connect_me_to_blocking(PHONE_NS, SERVICE_VIDEO, 0, 0);
if (fb_info.phone < 0) {