Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev 2024 → Rev 2025

/trunk/uspace/console/console.c
70,17 → 70,26
 
typedef struct {
keybuffer_t keybuffer; /**< Buffer for incoming keys. */
FIFO_CREATE_STATIC(keyrequests, ipc_callid_t , MAX_KEYREQUESTS_BUFFERED); /**< Buffer for unsatisfied request for keys. */
/** Buffer for unsatisfied request for keys. */
FIFO_CREATE_STATIC(keyrequests, ipc_callid_t,
MAX_KEYREQUESTS_BUFFERED);
int keyrequest_counter; /**< Number of requests in buffer. */
int client_phone; /**< Phone to connected client. */
int used; /**< 1 if this virtual console is connected to some client.*/
screenbuffer_t screenbuffer; /**< Screenbuffer for saving screen contents and related settings. */
int used; /**< 1 if this virtual console is
* connected to some client.*/
screenbuffer_t screenbuffer; /**< Screenbuffer for saving screen
* contents and related settings. */
} connection_t;
 
static connection_t connections[CONSOLE_COUNT]; /**< Array of data for virtual consoles */
static keyfield_t *interbuffer = NULL; /**< Pointer to memory shared with framebufer used for faster virt. console switching */
static connection_t connections[CONSOLE_COUNT]; /**< Array of data for virtual
* consoles */
static keyfield_t *interbuffer = NULL; /**< Pointer to memory shared
* with framebufer used for
* faster virtual console
*switching */
 
static int kernel_pixmap = -1; /**< Number of fb pixmap, where kernel console is stored */
static int kernel_pixmap = -1; /**< Number of fb pixmap, where kernel
* console is stored */
 
 
/** Find unused virtual console.
115,7 → 124,8
 
static void set_style(style_t *style)
{
async_msg_2(fb_info.phone, FB_SET_STYLE, style->fg_color, style->bg_color);
async_msg_2(fb_info.phone, FB_SET_STYLE, style->fg_color,
style->bg_color);
}
 
static void set_style_col(int fgcolor, int bgcolor)
137,34 → 147,30
screenbuffer_t *scr = &(connections[console].screenbuffer);
switch (key) {
case '\n':
scr->position_y += 1;
scr->position_x = 0;
case '\n':
scr->position_y += 1;
scr->position_x = 0;
break;
case '\r':
break;
case '\t':
scr->position_x += 8;
scr->position_x -= scr->position_x % 8;
break;
case '\b':
if (scr->position_x == 0)
break;
case '\r':
break;
case '\t':
scr->position_x += 8;
scr->position_x -= scr->position_x % 8;
break;
case '\b':
if (scr->position_x == 0)
break;
scr->position_x--;
if (console == active_console)
prtchr(' ', scr->position_y, scr->position_x);
screenbuffer_putchar(scr, ' ');
break;
default:
if (console == active_console)
prtchr(key, scr->position_y, scr->position_x);
 
scr->position_x--;
 
if (console == active_console)
prtchr(' ', scr->position_y, scr->position_x);
screenbuffer_putchar(scr, ' ');
break;
default:
if (console == active_console)
prtchr(key, scr->position_y, scr->position_x);
screenbuffer_putchar(scr, key);
scr->position_x++;
screenbuffer_putchar(scr, key);
scr->position_x++;
}
scr->position_y += (scr->position_x >= scr->size_x);
257,9 → 263,12
if (interbuffer) {
for (i = 0; i < conn->screenbuffer.size_x; i++)
for (j = 0; j < conn->screenbuffer.size_y; j++)
interbuffer[i + j*conn->screenbuffer.size_x] = *get_field_at(&(conn->screenbuffer),i, j);
interbuffer[i + j * conn->screenbuffer.size_x]
= *get_field_at(&(conn->screenbuffer),
i, j);
/* This call can preempt, but we are already at the end */
rc = async_req_2(fb_info.phone, FB_DRAW_TEXT_DATA, 0, 0, NULL, NULL);
rc = async_req_2(fb_info.phone, FB_DRAW_TEXT_DATA, 0, 0, NULL,
NULL);
};
if ((!interbuffer) || (rc != 0)) {
269,11 → 278,14
 
for (j = 0; j < conn->screenbuffer.size_y; j++)
for (i = 0; i < conn->screenbuffer.size_x; i++) {
field = get_field_at(&(conn->screenbuffer),i, j);
field = get_field_at(&(conn->screenbuffer), i,
j);
if (!style_same(*style, field->style))
set_style(&field->style);
style = &field->style;
if ((field->character == ' ') && (style_same(field->style, conn->screenbuffer.style)))
if ((field->character == ' ') &&
(style_same(field->style,
conn->screenbuffer.style)))
continue;
 
prtchr(field->character, j, i);
280,7 → 292,8
}
}
curs_goto(conn->screenbuffer.position_y, conn->screenbuffer.position_x);
curs_goto(conn->screenbuffer.position_y,
conn->screenbuffer.position_x);
curs_visibility(conn->screenbuffer.is_cursor_visible);
 
async_serialize_end();
310,7 → 323,8
retval = 0;
break;
case KBD_MS_MOVE:
gcons_mouse_move(IPC_GET_ARG1(call), IPC_GET_ARG2(call));
gcons_mouse_move(IPC_GET_ARG1(call),
IPC_GET_ARG2(call));
retval = 0;
break;
case KBD_PUSHCHAR:
321,7 → 335,10
/* switch to another virtual console */
conn = &connections[active_console];
// if ((c >= KBD_KEY_F1) && (c < KBD_KEY_F1 + CONSOLE_COUNT)) {
/*
* if ((c >= KBD_KEY_F1) && (c < KBD_KEY_F1 +
* CONSOLE_COUNT)) {
*/
if ((c >= 0x101) && (c < 0x101 + CONSOLE_COUNT)) {
if (c == 0x112)
change_console(KERNEL_CONSOLE);
333,7 → 350,8
/* if client is awaiting key, send it */
if (conn->keyrequest_counter > 0) {
conn->keyrequest_counter--;
ipc_answer_fast(fifo_pop(conn->keyrequests), 0, c, 0);
ipc_answer_fast(fifo_pop(conn->keyrequests), 0,
c, 0);
break;
}
385,7 → 403,8
/* Answer all pending requests */
while (conn->keyrequest_counter > 0) {
conn->keyrequest_counter--;
ipc_answer_fast(fifo_pop(conn->keyrequests), ENOENT, 0, 0);
ipc_answer_fast(fifo_pop(conn->keyrequests),
ENOENT, 0, 0);
break;
}
conn->used = 0;
404,13 → 423,12
break;
case CONSOLE_GOTO:
screenbuffer_goto(&conn->screenbuffer, IPC_GET_ARG2(call), IPC_GET_ARG1(call));
screenbuffer_goto(&conn->screenbuffer,
IPC_GET_ARG2(call), IPC_GET_ARG1(call));
if (consnum == active_console)
curs_goto(IPC_GET_ARG1(call),IPC_GET_ARG2(call));
curs_goto(IPC_GET_ARG1(call),
IPC_GET_ARG2(call));
break;
 
case CONSOLE_GETSIZE:
arg1 = fb_info.rows;
arg2 = fb_info.cols;
417,16 → 435,15
break;
case CONSOLE_FLUSH:
if (consnum == active_console)
async_req_2(fb_info.phone, FB_FLUSH, 0, 0, NULL, NULL);
async_req_2(fb_info.phone, FB_FLUSH, 0, 0,
NULL, NULL);
break;
case CONSOLE_SET_STYLE:
arg1 = IPC_GET_ARG1(call);
arg2 = IPC_GET_ARG2(call);
screenbuffer_set_style(&conn->screenbuffer,arg1, arg2);
if (consnum == active_console)
set_style_col(arg1, arg2);
break;
case CONSOLE_CURSOR_VISIBILITY:
arg1 = IPC_GET_ARG1(call);
437,17 → 454,20
case CONSOLE_GETCHAR:
if (keybuffer_empty(&conn->keybuffer)) {
/* buffer is empty -> store request */
if (conn->keyrequest_counter < MAX_KEYREQUESTS_BUFFERED) {
if (conn->keyrequest_counter <
MAX_KEYREQUESTS_BUFFERED) {
fifo_push(conn->keyrequests, callid);
conn->keyrequest_counter++;
} else {
/* no key available and too many requests => fail */
/*
* No key available and too many
* requests => fail.
*/
ipc_answer_fast(callid, ELIMIT, 0, 0);
}
continue;
};
keybuffer_pop(&conn->keybuffer, (int *)&arg1);
}
keybuffer_pop(&conn->keybuffer, (int *) &arg1);
break;
}
ipc_answer_fast(callid, 0, arg1, arg2);
464,18 → 484,21
/* Connect to keyboard driver */
 
while ((kbd_phone = ipc_connect_me_to(PHONE_NS, SERVICE_KEYBOARD, 0)) < 0) {
while ((kbd_phone = ipc_connect_me_to(PHONE_NS, SERVICE_KEYBOARD, 0))
< 0) {
usleep(10000);
};
}
if (ipc_connect_to_me(kbd_phone, SERVICE_CONSOLE, 0, &phonehash) != 0) {
if (ipc_connect_to_me(kbd_phone, SERVICE_CONSOLE, 0, &phonehash) != 0)
{
return -1;
};
}
async_new_connection(phonehash, 0, NULL, keyboard_events);
/* Connect to framebuffer driver */
while ((fb_info.phone = ipc_connect_me_to(PHONE_NS, SERVICE_VIDEO, 0)) < 0) {
while ((fb_info.phone = ipc_connect_me_to(PHONE_NS, SERVICE_VIDEO, 0))
< 0) {
usleep(10000);
}
489,7 → 512,8
/* Enable double buffering */
async_msg_2(fb_info.phone, FB_VIEWPORT_DB, (sysarg_t)-1, 1);
async_req_2(fb_info.phone, FB_GET_CSIZE, 0, 0, &(fb_info.rows), &(fb_info.cols));
async_req_2(fb_info.phone, FB_GET_CSIZE, 0, 0, &(fb_info.rows),
&(fb_info.cols));
set_style_col(DEFAULT_FOREGROUND, DEFAULT_BACKGROUND);
clrscr();
498,11 → 522,13
connections[i].used = 0;
keybuffer_init(&(connections[i].keybuffer));
connections[i].keyrequests.head = connections[i].keyrequests.tail = 0;
connections[i].keyrequests.head =
connections[i].keyrequests.tail = 0;
connections[i].keyrequests.items = MAX_KEYREQUESTS_BUFFERED;
connections[i].keyrequest_counter = 0;
if (screenbuffer_init(&(connections[i].screenbuffer), fb_info.cols, fb_info.rows ) == NULL) {
if (screenbuffer_init(&(connections[i].screenbuffer),
fb_info.cols, fb_info.rows) == NULL) {
/*FIXME: handle error */
return -1;
}
509,9 → 535,13
}
connections[KERNEL_CONSOLE].used = 1;
if ((interbuffer = mmap(NULL, sizeof(keyfield_t) * fb_info.cols * fb_info.rows , PROTO_READ|PROTO_WRITE, MAP_ANONYMOUS|MAP_PRIVATE, 0 ,0 )) != NULL) {
if (async_req_3(fb_info.phone, IPC_M_AS_AREA_SEND, (ipcarg_t)interbuffer, 0, AS_AREA_READ, NULL, NULL, NULL) != 0) {
munmap(interbuffer, sizeof(keyfield_t) * fb_info.cols * fb_info.rows);
if ((interbuffer = mmap(NULL, sizeof(keyfield_t) * fb_info.cols *
fb_info.rows, PROTO_READ | PROTO_WRITE, MAP_ANONYMOUS |
MAP_PRIVATE, 0, 0)) != NULL) {
if (async_req_3(fb_info.phone, IPC_M_AS_AREA_SEND, (ipcarg_t)
interbuffer, 0, AS_AREA_READ, NULL, NULL, NULL) != 0) {
munmap(interbuffer, sizeof(keyfield_t) * fb_info.cols
* fb_info.rows);
interbuffer = NULL;
}
}
522,7 → 552,7
/* Register at NS */
if (ipc_connect_to_me(PHONE_NS, SERVICE_CONSOLE, 0, &phonehash) != 0) {
return -1;
};
}
async_manager();