Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset 424cd43 in mainline


Ignore:
Timestamp:
2009-06-03T18:39:12Z (13 years ago)
Author:
Martin Decky <martin@…>
Branches:
lfn, master
Children:
8dc12ac
Parents:
b0a91acb
Message:

console server rewrite: use VFS_READ/VFS_WRITE for generic I/O, register separate virtual consoles using device mapper

Location:
uspace/srv/console
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/console/Makefile

    rb0a91acb r424cd43  
    4747        console.c \
    4848        screenbuffer.c \
    49         ../kbd/generic/key_buffer.c \
     49        ../kbd/generic/keybuffer.c \
    5050        gcons.c
    5151
  • uspace/srv/console/console.c

    rb0a91acb r424cd43  
    3737#include <ipc/ipc.h>
    3838#include <kbd.h>
    39 #include <kbd/keycode.h>
     39#include <io/keycode.h>
    4040#include <ipc/fb.h>
    4141#include <ipc/services.h>
    4242#include <errno.h>
    43 #include <key_buffer.h>
     43#include <keybuffer.h>
    4444#include <ipc/console.h>
    4545#include <unistd.h>
    4646#include <async.h>
    4747#include <libadt/fifo.h>
    48 #include <screenbuffer.h>
    4948#include <sys/mman.h>
    5049#include <stdio.h>
     
    5251#include <sysinfo.h>
    5352#include <event.h>
     53#include <devmap.h>
    5454
    5555#include "console.h"
    5656#include "gcons.h"
     57#include "screenbuffer.h"
    5758
    5859#define NAME  "console"
    5960
    60 #define MAX_KEYREQUESTS_BUFFERED  32
    61 
    62 /** Size of cwrite_buf. */
    63 #define CWRITE_BUF_SIZE  256
    64 
    65 /** Index of currently used virtual console.
    66  */
    67 int active_console = 0;
    68 int prev_console = 0;
     61#define MAX_DEVICE_NAME  32
    6962
    7063/** Phone to the keyboard driver. */
     
    7467struct {
    7568        int phone;      /**< Framebuffer phone */
     69        ipcarg_t cols;  /**< Framebuffer columns */
    7670        ipcarg_t rows;  /**< Framebuffer rows */
    77         ipcarg_t cols;  /**< Framebuffer columns */
    7871} fb_info;
    7972
    8073typedef struct {
    81         keybuffer_t keybuffer;        /**< Buffer for incoming keys. */
    82        
    83         /** Buffer for unsatisfied request for keys. */
    84         FIFO_CREATE_STATIC(keyrequests, ipc_callid_t,
    85             MAX_KEYREQUESTS_BUFFERED);
    86        
    87         int keyrequest_counter;       /**< Number of requests in buffer. */
    88         int client_phone;             /**< Phone to connected client. */
    89         int used;                     /**< 1 if this virtual console is
    90                                            connected to some client. */
    91         screenbuffer_t screenbuffer;  /**< Screenbuffer for saving screen
    92                                            contents and related settings. */
    93 } connection_t;
     74        size_t index;             /**< Console index */
     75        size_t refcount;          /**< Connection reference count */
     76        dev_handle_t dev_handle;  /**< Device handle */
     77        keybuffer_t keybuffer;    /**< Buffer for incoming keys. */
     78        screenbuffer_t scr;       /**< Screenbuffer for saving screen
     79                                       contents and related settings. */
     80} console_t;
    9481
    9582/** Array of data for virtual consoles */
    96 static connection_t connections[CONSOLE_COUNT];
     83static console_t consoles[CONSOLE_COUNT];
     84
     85static console_t *active_console = &consoles[0];
     86static console_t *prev_console = &consoles[0];
     87static console_t *kernel_console = &consoles[KERNEL_CONSOLE];
    9788
    9889/** Pointer to memory shared with framebufer used for
     
    10293/** Information on row-span yet unsent to FB driver. */
    10394struct {
    104         int row;  /**< Row where the span lies. */
    105         int col;  /**< Leftmost column of the span. */
    106         int cnt;  /**< Width of the span. */
     95        size_t col;  /**< Leftmost column of the span. */
     96        size_t row;  /**< Row where the span lies. */
     97        size_t cnt;  /**< Width of the span. */
    10798} fb_pending;
    10899
    109 /** Buffer for receiving data via the CONSOLE_WRITE call from the client. */
    110 static char cwrite_buf[CWRITE_BUF_SIZE];
    111 
    112 /** Find unused virtual console.
    113  *
    114  */
    115 static int find_free_connection(void)
    116 {
    117         int i;
    118        
    119         for (i = 0; i < CONSOLE_COUNT; i++) {
    120                 if (!connections[i].used)
    121                         return i;
    122         }
    123        
    124         return -1;
    125 }
    126 
    127 static void clrscr(void)
     100/** Pending input structure. */
     101typedef struct {
     102        link_t link;
     103        console_t *cons;      /**< Console waiting for input */
     104        ipc_callid_t rid;     /**< Call ID waiting for input */
     105        ipc_callid_t callid;  /**< Call ID waiting for IPC_DATA_READ */
     106       
     107        size_t pos;           /**< Position of the last stored data */
     108        size_t size;          /**< Size of ther buffer */
     109        char *data;           /**< Already stored data */
     110} pending_input_t;
     111
     112LIST_INITIALIZE(pending_input);
     113
     114/** Process pending input requests */
     115static void process_pending_input(void)
     116{
     117        async_serialize_start();
     118       
     119        link_t *cur;
     120       
     121loop:
     122        for (cur = pending_input.next; cur != &pending_input; cur = cur->next) {
     123                pending_input_t *pr = list_get_instance(cur, pending_input_t, link);
     124               
     125                console_event_t ev;
     126                if (keybuffer_pop(&pr->cons->keybuffer, &ev)) {
     127                       
     128                        if (pr->data != NULL) {
     129                                if (ev.type == KEY_PRESS) {
     130                                        pr->data[pr->pos] = ev.c;
     131                                        pr->pos++;
     132                                }
     133                        } else {
     134                                ipc_answer_4(pr->rid, EOK, ev.type, ev.key, ev.mods, ev.c);
     135                               
     136                                list_remove(cur);
     137                                free(pr);
     138                               
     139                                goto loop;
     140                        }
     141                }
     142               
     143                if ((pr->data != NULL) && (pr->pos == pr->size)) {
     144                        (void) ipc_data_read_finalize(pr->callid, pr->data, pr->size);
     145                        ipc_answer_1(pr->rid, EOK, pr->size);
     146                       
     147                        free(pr->data);
     148                        list_remove(cur);
     149                        free(pr);
     150                       
     151                        goto loop;
     152                }
     153        }
     154       
     155        async_serialize_end();
     156}
     157
     158static void curs_visibility(bool visible)
     159{
     160        async_msg_1(fb_info.phone, FB_CURSOR_VISIBILITY, visible);
     161}
     162
     163static void curs_hide_sync(void)
     164{
     165        ipc_call_sync_1_0(fb_info.phone, FB_CURSOR_VISIBILITY, false);
     166}
     167
     168static void curs_goto(size_t x, size_t y)
     169{
     170        async_msg_2(fb_info.phone, FB_CURSOR_GOTO, x, y);
     171}
     172
     173static void screen_clear(void)
    128174{
    129175        async_msg_0(fb_info.phone, FB_CLEAR);
    130176}
    131177
    132 static void curs_visibility(bool visible)
    133 {
    134         async_msg_1(fb_info.phone, FB_CURSOR_VISIBILITY, visible);
    135 }
    136 
    137 static void curs_hide_sync(void)
    138 {
    139         ipc_call_sync_1_0(fb_info.phone, FB_CURSOR_VISIBILITY, false);
    140 }
    141 
    142 static void curs_goto(int row, int col)
    143 {
    144         async_msg_2(fb_info.phone, FB_CURSOR_GOTO, row, col);
    145 }
    146 
    147178static void screen_yield(void)
    148179{
     
    167198static void set_style(int style)
    168199{
    169         async_msg_1(fb_info.phone, FB_SET_STYLE, style); 
     200        async_msg_1(fb_info.phone, FB_SET_STYLE, style);
    170201}
    171202
     
    197228
    198229/** Send an area of screenbuffer to the FB driver. */
    199 static void fb_update_area(connection_t *conn, int x, int y, int w, int h)
    200 {
    201         int i;
    202         int j;
    203         attrs_t *attrs;
    204         keyfield_t *field;
    205        
     230static void fb_update_area(console_t *cons, ipcarg_t x0, ipcarg_t y0, ipcarg_t width, ipcarg_t height)
     231{
    206232        if (interbuffer) {
    207                 for (j = 0; j < h; j++) {
    208                         for (i = 0; i < w; i++) {
    209                                 interbuffer[i + j * w] =
    210                                     *get_field_at(&conn->screenbuffer, x + i, y + j);
     233                ipcarg_t x;
     234                ipcarg_t y;
     235               
     236                for (y = 0; y < height; y++) {
     237                        for (x = 0; x < width; x++) {
     238                                interbuffer[y * width + x] =
     239                                    *get_field_at(&cons->scr, x0 + x, y0 + y);
    211240                        }
    212241                }
    213242               
    214243                async_req_4_0(fb_info.phone, FB_DRAW_TEXT_DATA,
    215                     x, y, w, h);
     244                    x0, y0, width, height);
    216245        }
    217246}
     
    220249static void fb_pending_flush(void)
    221250{
    222         screenbuffer_t *scr
    223             = &(connections[active_console].screenbuffer);
    224        
    225251        if (fb_pending.cnt > 0) {
    226                 fb_update_area(&connections[active_console], fb_pending.col,
     252                fb_update_area(active_console, fb_pending.col,
    227253                    fb_pending.row, fb_pending.cnt, 1);
    228254                fb_pending.cnt = 0;
     
    236262 *
    237263 */
    238 static void cell_mark_changed(int row, int col)
     264static void cell_mark_changed(size_t col, size_t row)
    239265{
    240266        if (fb_pending.cnt != 0) {
    241                 if ((row != fb_pending.row)
    242                     || (col != fb_pending.col + fb_pending.cnt)) {
     267                if ((col != fb_pending.col + fb_pending.cnt)
     268                    || (row != fb_pending.row)) {
    243269                        fb_pending_flush();
    244270                }
     
    246272       
    247273        if (fb_pending.cnt == 0) {
     274                fb_pending.col = col;
    248275                fb_pending.row = row;
    249                 fb_pending.col = col;
    250276        }
    251277       
     
    254280
    255281/** Print a character to the active VC with buffering. */
    256 static void fb_putchar(wchar_t c, int row, int col)
    257 {
    258         async_msg_3(fb_info.phone, FB_PUTCHAR, c, row, col);
     282static void fb_putchar(wchar_t c, ipcarg_t col, ipcarg_t row)
     283{
     284        async_msg_3(fb_info.phone, FB_PUTCHAR, c, col, row);
    259285}
    260286
    261287/** Process a character from the client (TTY emulation). */
    262 static void write_char(int console, wchar_t ch)
    263 {
    264         bool flush_cursor = false;
    265         screenbuffer_t *scr = &(connections[console].screenbuffer);
    266        
     288static void write_char(console_t *cons, wchar_t ch)
     289{
    267290        switch (ch) {
    268291        case '\n':
    269292                fb_pending_flush();
    270                 flush_cursor = true;
    271                 scr->position_y++;
    272                 scr->position_x = 0;
     293                cons->scr.position_y++;
     294                cons->scr.position_x = 0;
    273295                break;
    274296        case '\r':
    275297                break;
    276298        case '\t':
    277                 scr->position_x += 8;
    278                 scr->position_x -= scr->position_x % 8;
     299                cons->scr.position_x += 8;
     300                cons->scr.position_x -= cons->scr.position_x % 8;
    279301                break;
    280302        case '\b':
    281                 if (scr->position_x == 0)
    282                         break;
    283                 scr->position_x--;
    284                 if (console == active_console)
    285                         cell_mark_changed(scr->position_y, scr->position_x);
    286                 screenbuffer_putchar(scr, ' ');
     303                if (cons->scr.position_x == 0)
     304                        break;
     305                cons->scr.position_x--;
     306                if (cons == active_console)
     307                        cell_mark_changed(cons->scr.position_x, cons->scr.position_y);
     308                screenbuffer_putchar(&cons->scr, ' ');
    287309                break;
    288310        default:
    289                 if (console == active_console)
    290                         cell_mark_changed(scr->position_y, scr->position_x);
    291                
    292                 screenbuffer_putchar(scr, ch);
    293                 scr->position_x++;
    294         }
    295        
    296         if (scr->position_x >= scr->size_x) {
    297                 flush_cursor = true;
    298                 scr->position_y++;
    299         }
    300        
    301         if (scr->position_y >= scr->size_y) {
     311                if (cons == active_console)
     312                        cell_mark_changed(cons->scr.position_x, cons->scr.position_y);
     313               
     314                screenbuffer_putchar(&cons->scr, ch);
     315                cons->scr.position_x++;
     316        }
     317       
     318        if (cons->scr.position_x >= cons->scr.size_x)
     319                cons->scr.position_y++;
     320       
     321        if (cons->scr.position_y >= cons->scr.size_y) {
    302322                fb_pending_flush();
    303                 scr->position_y = scr->size_y - 1;
    304                 screenbuffer_clear_line(scr, scr->top_line);
    305                 scr->top_line = (scr->top_line + 1) % scr->size_y;
    306                 if (console == active_console)
     323                cons->scr.position_y = cons->scr.size_y - 1;
     324                screenbuffer_clear_line(&cons->scr, cons->scr.top_line);
     325                cons->scr.top_line = (cons->scr.top_line + 1) % cons->scr.size_y;
     326               
     327                if (cons == active_console)
    307328                        async_msg_1(fb_info.phone, FB_SCROLL, 1);
    308329        }
    309330       
    310         scr->position_x = scr->position_x % scr->size_x;
    311        
    312         if (console == active_console && flush_cursor)
    313                 curs_goto(scr->position_y, scr->position_x);
     331        cons->scr.position_x = cons->scr.position_x % cons->scr.size_x;
    314332}
    315333
    316334/** Switch to new console */
    317 static void change_console(int newcons)
    318 {
    319         connection_t *conn;
    320         int i;
    321         int j;
    322         int rc;
    323         keyfield_t *field;
    324         attrs_t *attrs;
    325        
    326         if (newcons == active_console)
     335static void change_console(console_t *cons)
     336{
     337        if (cons == active_console)
    327338                return;
    328339       
    329340        fb_pending_flush();
    330341       
    331         if (newcons == KERNEL_CONSOLE) {
     342        if (cons == kernel_console) {
    332343                async_serialize_start();
    333344                curs_hide_sync();
     
    337348                async_serialize_end();
    338349               
    339                
    340350                if (__SYSCALL0(SYS_DEBUG_ENABLE_CONSOLE)) {
    341351                        prev_console = active_console;
    342                         active_console = KERNEL_CONSOLE;
     352                        active_console = kernel_console;
    343353                } else
    344                         newcons = active_console;
    345         }
    346        
    347         if (newcons != KERNEL_CONSOLE) {
     354                        cons = active_console;
     355        }
     356       
     357        if (cons != kernel_console) {
     358                size_t x;
     359                size_t y;
     360                int rc = 0;
     361               
    348362                async_serialize_start();
    349363               
    350                 if (active_console == KERNEL_CONSOLE) {
     364                if (active_console == kernel_console) {
    351365                        screen_reclaim();
    352366                        kbd_reclaim();
     
    354368                }
    355369               
    356                 active_console = newcons;
    357                 gcons_change_console(newcons);
    358                 conn = &connections[active_console];
    359                
    360                 set_attrs(&conn->screenbuffer.attrs);
     370                active_console = cons;
     371                gcons_change_console(cons->index);
     372               
     373                set_attrs(&cons->scr.attrs);
    361374                curs_visibility(false);
    362375                if (interbuffer) {
    363                         for (j = 0; j < conn->screenbuffer.size_y; j++) {
    364                                 for (i = 0; i < conn->screenbuffer.size_x; i++) {
    365                                         unsigned int size_x;
    366                                        
    367                                         size_x = conn->screenbuffer.size_x;
    368                                         interbuffer[j * size_x + i] =
    369                                             *get_field_at(&conn->screenbuffer, i, j);
     376                        for (y = 0; y < cons->scr.size_y; y++) {
     377                                for (x = 0; x < cons->scr.size_x; x++) {
     378                                        interbuffer[y * cons->scr.size_x + x] =
     379                                            *get_field_at(&cons->scr, x, y);
    370380                                }
    371381                        }
     382                       
    372383                        /* This call can preempt, but we are already at the end */
    373384                        rc = async_req_4_0(fb_info.phone, FB_DRAW_TEXT_DATA,
    374                             0, 0, conn->screenbuffer.size_x,
    375                             conn->screenbuffer.size_y);
     385                            0, 0, cons->scr.size_x,
     386                            cons->scr.size_y);
    376387                }
    377388               
    378389                if ((!interbuffer) || (rc != 0)) {
    379                         set_attrs(&conn->screenbuffer.attrs);
    380                         clrscr();
    381                         attrs = &conn->screenbuffer.attrs;
    382                        
    383                         for (j = 0; j < conn->screenbuffer.size_y; j++)
    384                                 for (i = 0; i < conn->screenbuffer.size_x; i++) {
    385                                         field = get_field_at(&conn->screenbuffer, i, j);
    386                                         if (!attrs_same(*attrs, field->attrs))
     390                        set_attrs(&cons->scr.attrs);
     391                        screen_clear();
     392                       
     393                        for (y = 0; y < cons->scr.size_y; y++)
     394                                for (x = 0; x < cons->scr.size_x; x++) {
     395                                        keyfield_t *field = get_field_at(&cons->scr, x, y);
     396                                       
     397                                        if (!attrs_same(cons->scr.attrs, field->attrs))
    387398                                                set_attrs(&field->attrs);
    388                                         attrs = &field->attrs;
     399                                       
     400                                        cons->scr.attrs = field->attrs;
    389401                                        if ((field->character == ' ') &&
    390                                             (attrs_same(field->attrs, conn->screenbuffer.attrs)))
     402                                            (attrs_same(field->attrs, cons->scr.attrs)))
    391403                                                continue;
    392404                                       
    393                                         fb_putchar(field->character, j, i);
     405                                        fb_putchar(field->character, x, y);
    394406                                }
    395407                }
    396408               
    397                 curs_goto(conn->screenbuffer.position_y,
    398                     conn->screenbuffer.position_x);
    399                 curs_visibility(conn->screenbuffer.is_cursor_visible);
     409                curs_goto(cons->scr.position_x, cons->scr.position_y);
     410                curs_visibility(cons->scr.is_cursor_visible);
    400411               
    401412                async_serialize_end();
     
    406417static void keyboard_events(ipc_callid_t iid, ipc_call_t *icall)
    407418{
    408         ipc_callid_t callid;
    409         ipc_call_t call;
    410         int retval;
    411         kbd_event_t ev;
    412         connection_t *conn;
    413         int newcon;
    414        
    415         /* Ignore parameters, the connection is alread opened */
     419        /* Ignore parameters, the connection is already opened */
    416420        while (true) {
    417                 callid = async_get_call(&call);
     421               
     422                ipc_call_t call;
     423                ipc_callid_t callid = async_get_call(&call);
     424               
     425                int retval;
     426                console_event_t ev;
     427               
    418428                switch (IPC_GET_METHOD(call)) {
    419429                case IPC_M_PHONE_HUNGUP:
    420430                        /* TODO: Handle hangup */
    421431                        return;
    422                 case KBD_MS_LEFT:
    423                         newcon = gcons_mouse_btn(IPC_GET_ARG1(call));
    424                         if (newcon != -1)
    425                                 change_console(newcon);
    426                         retval = 0;
    427                         break;
    428                 case KBD_MS_MOVE:
    429                         gcons_mouse_move(IPC_GET_ARG1(call),
    430                             IPC_GET_ARG2(call));
    431                         retval = 0;
    432                         break;
    433432                case KBD_EVENT:
    434433                        /* Got event from keyboard driver. */
     
    439438                        ev.c = IPC_GET_ARG4(call);
    440439                       
    441                         /* Switch to another virtual console */
    442                         conn = &connections[active_console];
    443                        
    444440                        if ((ev.key >= KC_F1) && (ev.key < KC_F1 +
    445441                            CONSOLE_COUNT) && ((ev.mods & KM_CTRL) == 0)) {
    446                                 if (ev.key == KC_F12)
    447                                         change_console(KERNEL_CONSOLE);
     442                                if (ev.key == KC_F1 + KERNEL_CONSOLE)
     443                                        change_console(kernel_console);
    448444                                else
    449                                         change_console(ev.key - KC_F1);
     445                                        change_console(&consoles[ev.key - KC_F1]);
    450446                                break;
    451447                        }
    452448                       
    453                         /* If client is awaiting key, send it */
    454                         if (conn->keyrequest_counter > 0) {
    455                                 conn->keyrequest_counter--;
    456                                 ipc_answer_4(fifo_pop(conn->keyrequests), EOK,
    457                                     ev.type, ev.key, ev.mods, ev.c);
    458                                 break;
    459                         }
    460                        
    461                         keybuffer_push(&conn->keybuffer, &ev);
    462                         retval = 0;
    463                        
     449                        keybuffer_push(&active_console->keybuffer, &ev);
    464450                        break;
    465451                default:
     
    470456}
    471457
    472 /** Handle CONSOLE_WRITE call. */
    473 static void cons_write(int consnum, ipc_callid_t rid, ipc_call_t *request)
     458static void cons_write(console_t *cons, ipc_callid_t rid, ipc_call_t *request)
    474459{
    475460        ipc_callid_t callid;
    476461        size_t size;
    477         wchar_t ch;
    478         size_t off;
    479        
    480462        if (!ipc_data_write_receive(&callid, &size)) {
    481463                ipc_answer_0(callid, EINVAL);
     
    484466        }
    485467       
    486         if (size > CWRITE_BUF_SIZE)
    487                 size = CWRITE_BUF_SIZE;
    488        
    489         (void) ipc_data_write_finalize(callid, cwrite_buf, size);
     468        char *buf = (char *) malloc(size);
     469        if (buf == NULL) {
     470                ipc_answer_0(callid, ENOMEM);
     471                ipc_answer_0(rid, ENOMEM);
     472                return;
     473        }
     474       
     475        (void) ipc_data_write_finalize(callid, buf, size);
    490476       
    491477        async_serialize_start();
    492478       
    493         off = 0;
     479        size_t off = 0;
    494480        while (off < size) {
    495                 ch = str_decode(cwrite_buf, &off, size);
    496                 write_char(consnum, ch);
    497         }
     481                wchar_t ch = str_decode(buf, &off, size);
     482                write_char(cons, ch);
     483        }
     484       
     485        if (cons == active_console)
     486                curs_goto(cons->scr.position_x, cons->scr.position_y);
    498487       
    499488        async_serialize_end();
    500489       
    501         gcons_notify_char(consnum);
     490        gcons_notify_char(cons->index);
    502491        ipc_answer_1(rid, EOK, size);
     492       
     493        free(buf);
     494}
     495
     496static void cons_read(console_t *cons, ipc_callid_t rid, ipc_call_t *request)
     497{
     498        ipc_callid_t callid;
     499        size_t size;
     500        if (!ipc_data_read_receive(&callid, &size)) {
     501                ipc_answer_0(callid, EINVAL);
     502                ipc_answer_0(rid, EINVAL);
     503                return;
     504        }
     505       
     506        char *buf = (char *) malloc(size);
     507        if (buf == NULL) {
     508                ipc_answer_0(callid, ENOMEM);
     509                ipc_answer_0(rid, ENOMEM);
     510                return;
     511        }
     512       
     513        async_serialize_start();
     514       
     515        size_t pos = 0;
     516        console_event_t ev;
     517        while ((keybuffer_pop(&cons->keybuffer, &ev)) && (pos < size)) {
     518                if (ev.type == KEY_PRESS) {
     519                        buf[pos] = ev.c;
     520                        pos++;
     521                }
     522        }
     523       
     524        if (pos == size) {
     525                (void) ipc_data_read_finalize(callid, buf, size);
     526                ipc_answer_1(rid, EOK, size);
     527                free(buf);
     528        } else {
     529                pending_input_t *pr = (pending_input_t *) malloc(sizeof(pending_input_t));
     530                if (!pr) {
     531                        ipc_answer_0(rid, ENOMEM);
     532                        free(buf);
     533                        async_serialize_end();
     534                        return;
     535                }
     536               
     537                pr->cons = cons;
     538                pr->rid = rid;
     539                pr->callid = callid;
     540                pr->pos = pos;
     541                pr->size = size;
     542                pr->data = buf;
     543                list_append(&pr->link, &pending_input);
     544        }
     545       
     546        async_serialize_end();
     547}
     548
     549static void cons_get_event(console_t *cons, ipc_callid_t rid, ipc_call_t *request)
     550{
     551        async_serialize_start();
     552       
     553        console_event_t ev;
     554        if (keybuffer_pop(&cons->keybuffer, &ev)) {
     555                ipc_answer_4(rid, EOK, ev.type, ev.key, ev.mods, ev.c);
     556        } else {
     557                pending_input_t *pr = (pending_input_t *) malloc(sizeof(pending_input_t));
     558                if (!pr) {
     559                        ipc_answer_0(rid, ENOMEM);
     560                        async_serialize_end();
     561                        return;
     562                }
     563               
     564                pr->cons = cons;
     565                pr->rid = rid;
     566                pr->callid = 0;
     567                pr->data = NULL;
     568                list_append(&pr->link, &pending_input);
     569        }
     570       
     571        async_serialize_end();
    503572}
    504573
     
    506575static void client_connection(ipc_callid_t iid, ipc_call_t *icall)
    507576{
     577        console_t *cons = NULL;
     578       
     579        size_t i;
     580        for (i = 0; i < CONSOLE_COUNT; i++) {
     581                if (i == KERNEL_CONSOLE)
     582                        continue;
     583               
     584                if (consoles[i].dev_handle == (dev_handle_t) IPC_GET_ARG1(*icall)) {
     585                        cons = &consoles[i];
     586                        break;
     587                }
     588        }
     589       
     590        if (cons == NULL) {
     591                ipc_answer_0(iid, ENOENT);
     592                return;
     593        }
     594       
    508595        ipc_callid_t callid;
    509596        ipc_call_t call;
    510         int consnum;
    511         ipcarg_t arg1, arg2, arg3, arg4;
    512         connection_t *conn;
    513         screenbuffer_t *scr;
    514        
    515         if ((consnum = find_free_connection()) == -1) {
    516                 ipc_answer_0(iid, ELIMIT);
    517                 return;
    518         }
    519         conn = &connections[consnum];
    520         conn->used = 1;
     597        ipcarg_t arg1;
     598        ipcarg_t arg2;
     599        ipcarg_t arg3;
    521600       
    522601        async_serialize_start();
    523         gcons_notify_connect(consnum);
    524         conn->client_phone = IPC_GET_ARG5(*icall);
    525         screenbuffer_clear(&conn->screenbuffer);
    526         if (consnum == active_console)
    527                 clrscr();
     602        if (cons->refcount == 0)
     603                gcons_notify_connect(cons->index);
     604       
     605        cons->refcount++;
    528606       
    529607        /* Accept the connection */
     
    538616                arg2 = 0;
    539617                arg3 = 0;
    540                 arg4 = 0;
    541618               
    542619                switch (IPC_GET_METHOD(call)) {
    543620                case IPC_M_PHONE_HUNGUP:
    544                         gcons_notify_disconnect(consnum);
    545                        
    546                         /* Answer all pending requests */
    547                         while (conn->keyrequest_counter > 0) {
    548                                 conn->keyrequest_counter--;
    549                                 ipc_answer_0(fifo_pop(conn->keyrequests),
    550                                     ENOENT);
    551                                 break;
    552                         }
    553                         conn->used = 0;
     621                        cons->refcount--;
     622                        if (cons->refcount == 0)
     623                                gcons_notify_disconnect(cons->index);
    554624                        return;
    555                 case CONSOLE_PUTCHAR:
    556                         write_char(consnum, IPC_GET_ARG1(call));
    557                         gcons_notify_char(consnum);
    558                         break;
    559                 case CONSOLE_WRITE:
     625                case VFS_READ:
    560626                        async_serialize_end();
    561                         cons_write(consnum, callid, &call);
     627                        cons_read(cons, callid, &call);
    562628                        async_serialize_start();
    563629                        continue;
     630                case VFS_WRITE:
     631                        async_serialize_end();
     632                        cons_write(cons, callid, &call);
     633                        async_serialize_start();
     634                        continue;
     635                case VFS_SYNC:
     636                        fb_pending_flush();
     637                        if (cons == active_console) {
     638                                async_req_0_0(fb_info.phone, FB_FLUSH);
     639                               
     640                                curs_goto(cons->scr.position_x, cons->scr.position_y);
     641                        }
     642                        break;
    564643                case CONSOLE_CLEAR:
    565644                        /* Send message to fb */
    566                         if (consnum == active_console) {
    567                                 async_msg_0(fb_info.phone, FB_CLEAR);
    568                         }
    569                        
    570                         screenbuffer_clear(&conn->screenbuffer);
     645                        if (cons == active_console)
     646                                async_msg_0(fb_info.phone, FB_CLEAR);
     647                       
     648                        screenbuffer_clear(&cons->scr);
    571649                       
    572650                        break;
    573651                case CONSOLE_GOTO:
    574                         screenbuffer_goto(&conn->screenbuffer,
    575                             IPC_GET_ARG2(call), IPC_GET_ARG1(call));
    576                         if (consnum == active_console)
     652                        screenbuffer_goto(&cons->scr,
     653                            IPC_GET_ARG1(call), IPC_GET_ARG2(call));
     654                        if (cons == active_console)
    577655                                curs_goto(IPC_GET_ARG1(call),
    578656                                    IPC_GET_ARG2(call));
    579657                        break;
    580                 case CONSOLE_GETSIZE:
    581                         arg1 = fb_info.rows;
    582                         arg2 = fb_info.cols;
    583                         break;
    584                 case CONSOLE_FLUSH:
    585                         fb_pending_flush();
    586                         if (consnum == active_console) {
    587                                 async_req_0_0(fb_info.phone, FB_FLUSH);
    588                                
    589                                 scr = &(connections[consnum].screenbuffer);
    590                                 curs_goto(scr->position_y, scr->position_x);
    591                         }
     658                case CONSOLE_GET_SIZE:
     659                        arg1 = fb_info.cols;
     660                        arg2 = fb_info.rows;
    592661                        break;
    593662                case CONSOLE_SET_STYLE:
    594663                        fb_pending_flush();
    595664                        arg1 = IPC_GET_ARG1(call);
    596                         screenbuffer_set_style(&conn->screenbuffer, arg1);
    597                         if (consnum == active_console)
     665                        screenbuffer_set_style(&cons->scr, arg1);
     666                        if (cons == active_console)
    598667                                set_style(arg1);
    599668                        break;
     
    603672                        arg2 = IPC_GET_ARG2(call);
    604673                        arg3 = IPC_GET_ARG3(call);
    605                         screenbuffer_set_color(&conn->screenbuffer, arg1,
    606                             arg2, arg3);
    607                         if (consnum == active_console)
     674                        screenbuffer_set_color(&cons->scr, arg1, arg2, arg3);
     675                        if (cons == active_console)
    608676                                set_color(arg1, arg2, arg3);
    609677                        break;
     
    612680                        arg1 = IPC_GET_ARG1(call);
    613681                        arg2 = IPC_GET_ARG2(call);
    614                         screenbuffer_set_rgb_color(&conn->screenbuffer, arg1,
    615                             arg2);
    616                         if (consnum == active_console)
     682                        screenbuffer_set_rgb_color(&cons->scr, arg1, arg2);
     683                        if (cons == active_console)
    617684                                set_rgb_color(arg1, arg2);
    618685                        break;
     
    620687                        fb_pending_flush();
    621688                        arg1 = IPC_GET_ARG1(call);
    622                         conn->screenbuffer.is_cursor_visible = arg1;
    623                         if (consnum == active_console)
     689                        cons->scr.is_cursor_visible = arg1;
     690                        if (cons == active_console)
    624691                                curs_visibility(arg1);
    625692                        break;
    626                 case CONSOLE_GETKEY:
    627                         if (keybuffer_empty(&conn->keybuffer)) {
    628                                 /* buffer is empty -> store request */
    629                                 if (conn->keyrequest_counter <
    630                                         MAX_KEYREQUESTS_BUFFERED) {
    631                                         fifo_push(conn->keyrequests, callid);
    632                                         conn->keyrequest_counter++;
    633                                 } else {
    634                                         /*
    635                                          * No key available and too many
    636                                          * requests => fail.
    637                                         */
    638                                         ipc_answer_0(callid, ELIMIT);
    639                                 }
    640                                 continue;
    641                         }
    642                         kbd_event_t ev;
    643                         keybuffer_pop(&conn->keybuffer, &ev);
    644                         arg1 = ev.type;
    645                         arg2 = ev.key;
    646                         arg3 = ev.mods;
    647                         arg4 = ev.c;
    648                         break;
     693                case CONSOLE_GET_EVENT:
     694                        async_serialize_end();
     695                        cons_get_event(cons, callid, &call);
     696                        async_serialize_start();
     697                        continue;
    649698                case CONSOLE_KCON_ENABLE:
    650                         change_console(KERNEL_CONSOLE);
    651                         break;
    652                 }
    653                 ipc_answer_4(callid, EOK, arg1, arg2, arg3, arg4);
     699                        change_console(kernel_console);
     700                        break;
     701                }
     702                ipc_answer_3(callid, EOK, arg1, arg2, arg3);
    654703        }
    655704}
     
    660709}
    661710
    662 int main(int argc, char *argv[])
    663 {
    664         printf(NAME ": HelenOS Console service\n");
    665        
    666         ipcarg_t phonehash;
    667         size_t ib_size;
    668         int i;
    669        
    670         async_set_client_connection(client_connection);
    671        
     711static bool console_init(void)
     712{
    672713        /* Connect to keyboard driver */
     714       
    673715        kbd_phone = ipc_connect_me_to_blocking(PHONE_NS, SERVICE_KEYBOARD, 0, 0);
    674716        if (kbd_phone < 0) {
    675717                printf(NAME ": Failed to connect to keyboard service\n");
    676                 return -1;
    677         }
    678        
     718                return false;
     719        }
     720       
     721        ipcarg_t phonehash;
    679722        if (ipc_connect_to_me(kbd_phone, SERVICE_CONSOLE, 0, 0, &phonehash) != 0) {
    680723                printf(NAME ": Failed to create callback from keyboard service\n");
    681                 return -1;
    682         }
    683        
     724                return false;
     725        }
     726       
     727        async_set_pending(process_pending_input);
    684728        async_new_connection(phonehash, 0, NULL, keyboard_events);
    685729       
     
    691735        }
    692736       
    693         /* Disable kernel output to the console */
    694         __SYSCALL0(SYS_DEBUG_DISABLE_CONSOLE);
     737        /* Register driver */
     738        int rc = devmap_driver_register(NAME, client_connection);
     739        if (rc < 0) {
     740                printf(NAME ": Unable to register driver (%d)\n", rc);
     741                return false;
     742        }
    695743       
    696744        /* Initialize gcons */
    697745        gcons_init(fb_info.phone);
    698         /* Synchronize, the gcons can have something in queue */
     746       
     747        /* Synchronize, the gcons could put something in queue */
    699748        async_req_0_0(fb_info.phone, FB_FLUSH);
    700        
    701         async_req_0_2(fb_info.phone, FB_GET_CSIZE, &fb_info.rows,
    702             &fb_info.cols);
    703         set_rgb_color(DEFAULT_FOREGROUND, DEFAULT_BACKGROUND);
    704         clrscr();
    705        
    706         /* Init virtual consoles */
    707         for (i = 0; i < CONSOLE_COUNT; i++) {
    708                 connections[i].used = 0;
    709                 keybuffer_init(&connections[i].keybuffer);
    710                
    711                 connections[i].keyrequests.head = 0;
    712                 connections[i].keyrequests.tail = 0;
    713                 connections[i].keyrequests.items = MAX_KEYREQUESTS_BUFFERED;
    714                 connections[i].keyrequest_counter = 0;
    715                
    716                 if (screenbuffer_init(&connections[i].screenbuffer,
    717                     fb_info.cols, fb_info.rows) == NULL) {
    718                         /* FIXME: handle error */
    719                         return -1;
    720                 }
    721         }
    722         connections[KERNEL_CONSOLE].used = 1;
     749        async_req_0_2(fb_info.phone, FB_GET_CSIZE, &fb_info.cols, &fb_info.rows);
    723750       
    724751        /* Set up shared memory buffer. */
    725         ib_size = sizeof(keyfield_t) * fb_info.cols * fb_info.rows;
     752        size_t ib_size = sizeof(keyfield_t) * fb_info.cols * fb_info.rows;
    726753        interbuffer = as_get_mappable_page(ib_size);
    727754       
    728         fb_pending.cnt = 0;
    729        
    730755        if (as_area_create(interbuffer, ib_size, AS_AREA_READ |
    731             AS_AREA_WRITE | AS_AREA_CACHEABLE) != interbuffer) {
     756            AS_AREA_WRITE | AS_AREA_CACHEABLE) != interbuffer)
    732757                interbuffer = NULL;
    733         }
    734758       
    735759        if (interbuffer) {
     
    741765        }
    742766       
     767        fb_pending.cnt = 0;
     768       
     769        /* Inititalize consoles */
     770        size_t i;
     771        for (i = 0; i < CONSOLE_COUNT; i++) {
     772                if (i != KERNEL_CONSOLE) {
     773                        if (screenbuffer_init(&consoles[i].scr,
     774                            fb_info.cols, fb_info.rows) == NULL) {
     775                                printf(NAME ": Unable to allocate screen buffer %u\n", i);
     776                                return false;
     777                        }
     778                        screenbuffer_clear(&consoles[i].scr);
     779                        keybuffer_init(&consoles[i].keybuffer);
     780                        consoles[i].index = i;
     781                        consoles[i].refcount = 0;
     782                       
     783                        char vc[MAX_DEVICE_NAME];
     784                        snprintf(vc, MAX_DEVICE_NAME, "vc%u", i);
     785                       
     786                        if (devmap_device_register(vc, &consoles[i].dev_handle) != EOK) {
     787                                devmap_hangup_phone(DEVMAP_DRIVER);
     788                                printf(NAME ": Unable to register device %s\n", vc);
     789                                return false;
     790                        }
     791                }
     792        }
     793       
     794        /* Initialize the screen */
     795        set_rgb_color(DEFAULT_FOREGROUND, DEFAULT_BACKGROUND);
     796        screen_clear();
    743797        curs_goto(0, 0);
    744         curs_visibility(
    745             connections[active_console].screenbuffer.is_cursor_visible);
    746        
    747         /* Register at NS */
    748         if (ipc_connect_to_me(PHONE_NS, SERVICE_CONSOLE, 0, 0, &phonehash) != 0)
    749                 return -1;
     798        curs_visibility(active_console->scr.is_cursor_visible);
    750799       
    751800        /* Receive kernel notifications */
     
    755804        async_set_interrupt_received(interrupt_received);
    756805       
    757         // FIXME: avoid connectiong to itself, keep using klog
    758         // printf(NAME ": Accepting connections\n");
     806        return true;
     807}
     808
     809int main(int argc, char *argv[])
     810{
     811        printf(NAME ": HelenOS Console service\n");
     812       
     813        /* Disable kernel output to the console */
     814        __SYSCALL0(SYS_DEBUG_DISABLE_CONSOLE);
     815       
     816        if (!console_init()) {
     817                __SYSCALL0(SYS_DEBUG_ENABLE_CONSOLE);
     818                return -1;
     819        }
     820       
     821        printf(NAME ": Accepting connections\n");
    759822        async_manager();
    760823       
  • uspace/srv/console/gcons.c

    rb0a91acb r424cd43  
    4040#include <string.h>
    4141#include <align.h>
     42#include <bool.h>
    4243
    4344#include "console.h"
     
    5556#define MAIN_COLOR  0xffffff
    5657
    57 static int use_gcons = 0;
    58 static ipcarg_t xres,yres;
     58static bool use_gcons = false;
     59static ipcarg_t xres;
     60static ipcarg_t yres;
    5961
    6062enum butstate {
     
    7880static int animation = -1;
    7981
    80 static int active_console = 0;
     82static size_t active_console = 0;
     83
     84size_t mouse_x;
     85size_t mouse_y;
     86
     87bool btn_pressed;
     88size_t btn_x;
     89size_t btn_y;
    8190
    8291static void vp_switch(int vp)
     
    8695
    8796/** Create view port */
    88 static int vp_create(unsigned int x, unsigned int y, unsigned int width,
    89     unsigned int height)
     97static int vp_create(size_t x, size_t y, size_t width, size_t height)
    9098{
    9199        return async_req_2_0(fbphone, FB_VIEWPORT_CREATE, (x << 16) | y,
     
    98106}
    99107
    100 static void set_rgb_color(int fgcolor, int bgcolor)
     108static void set_rgb_color(uint32_t fgcolor, uint32_t bgcolor)
    101109{
    102110        async_msg_2(fbphone, FB_SET_RGB_COLOR, fgcolor, bgcolor);
     
    104112
    105113/** Transparent putchar */
    106 static void tran_putch(char c, int row, int col)
    107 {
    108         async_msg_3(fbphone, FB_PUTCHAR, c, row, col);
     114static void tran_putch(wchar_t ch, size_t col, size_t row)
     115{
     116        async_msg_3(fbphone, FB_PUTCHAR, ch, col, row);
    109117}
    110118
    111119/** Redraw the button showing state of a given console */
    112 static void redraw_state(int consnum)
    113 {
    114         char data[5];
    115         int i;
    116         enum butstate state = console_state[consnum];
    117        
    118         vp_switch(cstatus_vp[consnum]);
     120static void redraw_state(size_t index)
     121{
     122        vp_switch(cstatus_vp[index]);
     123       
     124        enum butstate state = console_state[index];
     125       
    119126        if (ic_pixmaps[state] != -1)
    120                 async_msg_2(fbphone, FB_VP_DRAW_PIXMAP, cstatus_vp[consnum],
     127                async_msg_2(fbphone, FB_VP_DRAW_PIXMAP, cstatus_vp[index],
    121128                    ic_pixmaps[state]);
    122129       
    123         if (state != CONS_DISCONNECTED && state != CONS_KERNEL &&
    124             state != CONS_DISCONNECTED_SEL) {
    125                 snprintf(data, 5, "%d", consnum + 1);
    126                 for (i = 0; data[i]; i++)
    127                         tran_putch(data[i], 1, 2 + i);
     130        if ((state != CONS_DISCONNECTED) && (state != CONS_KERNEL)
     131            && (state != CONS_DISCONNECTED_SEL)) {
     132               
     133                char data[5];
     134                snprintf(data, 5, "%u", index + 1);
     135               
     136                size_t i;
     137                for (i = 0; data[i] != 0; i++)
     138                        tran_putch(data[i], 2 + i, 1);
    128139        }
    129140}
    130141
    131142/** Notification run on changing console (except kernel console) */
    132 void gcons_change_console(int consnum)
    133 {
    134         int i;
    135        
     143void gcons_change_console(size_t index)
     144{
    136145        if (!use_gcons)
    137146                return;
    138147       
    139148        if (active_console == KERNEL_CONSOLE) {
     149                size_t i;
     150               
    140151                for (i = 0; i < CONSOLE_COUNT; i++)
    141152                        redraw_state(i);
     153               
    142154                if (animation != -1)
    143155                        async_msg_1(fbphone, FB_ANIM_START, animation);
     
    147159                else
    148160                        console_state[active_console] = CONS_IDLE;
     161               
    149162                redraw_state(active_console);
    150163        }
    151         active_console = consnum;
    152        
    153         if (console_state[consnum] == CONS_DISCONNECTED) {
    154                 console_state[consnum] = CONS_DISCONNECTED_SEL;
    155                 redraw_state(consnum);
    156         } else
    157                 console_state[consnum] = CONS_SELECTED;
    158         redraw_state(consnum);
    159        
     164       
     165        active_console = index;
     166       
     167        if ((console_state[index] == CONS_DISCONNECTED)
     168            || (console_state[index] == CONS_DISCONNECTED_SEL))
     169                console_state[index] = CONS_DISCONNECTED_SEL;
     170        else
     171                console_state[index] = CONS_SELECTED;
     172       
     173        redraw_state(index);
    160174        vp_switch(console_vp);
    161175}
    162176
    163177/** Notification function that gets called on new output to virtual console */
    164 void gcons_notify_char(int consnum)
     178void gcons_notify_char(size_t index)
    165179{
    166180        if (!use_gcons)
    167181                return;
    168182       
    169         if ((consnum == active_console) ||
    170             (console_state[consnum] == CONS_HAS_DATA))
    171                 return;
    172        
    173         console_state[consnum] = CONS_HAS_DATA;
     183        if ((index == active_console)
     184            || (console_state[index] == CONS_HAS_DATA))
     185                return;
     186       
     187        console_state[index] = CONS_HAS_DATA;
    174188       
    175189        if (active_console == KERNEL_CONSOLE)
    176190                return;
    177191       
    178         redraw_state(consnum);
    179        
     192        redraw_state(index);
    180193        vp_switch(console_vp);
    181194}
    182195
    183196/** Notification function called on service disconnect from console */
    184 void gcons_notify_disconnect(int consnum)
     197void gcons_notify_disconnect(size_t index)
    185198{
    186199        if (!use_gcons)
    187200                return;
    188201       
    189         if (active_console == consnum)
    190                 console_state[consnum] = CONS_DISCONNECTED_SEL;
     202        if (index == active_console)
     203                console_state[index] = CONS_DISCONNECTED_SEL;
    191204        else
    192                 console_state[consnum] = CONS_DISCONNECTED;
     205                console_state[index] = CONS_DISCONNECTED;
    193206       
    194207        if (active_console == KERNEL_CONSOLE)
    195208                return;
    196209       
    197         redraw_state(consnum);
     210        redraw_state(index);
    198211        vp_switch(console_vp);
    199212}
    200213
    201214/** Notification function called on console connect */
    202 void gcons_notify_connect(int consnum)
     215void gcons_notify_connect(size_t index)
    203216{
    204217        if (!use_gcons)
    205218                return;
    206219       
    207         if (active_console == consnum)
    208                 console_state[consnum] = CONS_SELECTED;
     220        if (index == active_console)
     221                console_state[index] = CONS_SELECTED;
    209222        else
    210                 console_state[consnum] = CONS_IDLE;
     223                console_state[index] = CONS_IDLE;
    211224       
    212225        if (active_console == KERNEL_CONSOLE)
    213226                return;
    214227       
    215         redraw_state(consnum);
     228        redraw_state(index);
    216229        vp_switch(console_vp);
    217230}
     
    227240}
    228241
    229 /** Return x, where left <= x <= right && |a-x|==min(|a-x|) is smallest */
    230 static inline int limit(int a, int left, int right)
     242/** Return x, where left <= x <= right && |a-x| == min(|a-x|) is smallest */
     243static inline int limit(size_t a, size_t left, size_t right)
    231244{
    232245        if (a < left)
    233246                a = left;
     247       
    234248        if (a >= right)
    235249                a = right - 1;
     250       
    236251        return a;
    237252}
    238 
    239 int mouse_x, mouse_y;
    240 int btn_pressed, btn_x, btn_y;
    241253
    242254/** Handle mouse move
     
    245257 * @param dy Delta Y of mouse move
    246258 */
    247 void gcons_mouse_move(int dx, int dy)
     259void gcons_mouse_move(ssize_t dx, ssize_t dy)
    248260{
    249261        mouse_x = limit(mouse_x + dx, 0, xres);
     
    273285/** Handle mouse click
    274286 *
    275  * @param state New state (1-pressed, 0-depressed)
    276  */
    277 int gcons_mouse_btn(int state)
     287 * @param state New state (true - pressed, false - depressed)
     288 */
     289int gcons_mouse_btn(bool state)
    278290{
    279291        int conbut;
     
    282294                conbut = gcons_find_conbut(mouse_x, mouse_y);
    283295                if (conbut != -1) {
    284                         btn_pressed = 1;
     296                        btn_pressed = true;
    285297                        btn_x = mouse_x;
    286298                        btn_y = mouse_y;
     
    292304                return -1;
    293305       
    294         btn_pressed = 0;
     306        btn_pressed = false;
    295307       
    296308        conbut = gcons_find_conbut(mouse_x, mouse_y);
     
    374386 * @param data PPM data
    375387 * @param size PPM data size
     388 *
    376389 * @return Pixmap identification
    377  */
    378 static int make_pixmap(char *data, int size)
     390 *
     391 */
     392static int make_pixmap(char *data, size_t size)
    379393{
    380394        char *shm;
     
    465479void gcons_init(int phone)
    466480{
    467         int rc;
    468         int i;
    469         int status_start = STATUS_START;
    470        
    471481        fbphone = phone;
    472482       
    473         rc = async_req_0_2(phone, FB_GET_RESOLUTION, &xres, &yres);
     483        int rc = async_req_0_2(phone, FB_GET_RESOLUTION, &xres, &yres);
    474484        if (rc)
    475485                return;
     
    484494            ALIGN_DOWN(xres - 2 * CONSOLE_MARGIN, 8),
    485495            ALIGN_DOWN(yres - (CONSOLE_TOP + CONSOLE_MARGIN), 16));
     496       
    486497        if (console_vp < 0)
    487498                return;
    488499       
    489500        /* Create status buttons */
    490         status_start += (xres - 800) / 2;
     501        size_t status_start = STATUS_START + (xres - 800) / 2;
     502        size_t i;
    491503        for (i = 0; i < CONSOLE_COUNT; i++) {
    492504                cstatus_vp[i] = vp_create(status_start + CONSOLE_MARGIN +
    493505                    i * (STATUS_WIDTH + STATUS_SPACE), STATUS_TOP,
    494506                    STATUS_WIDTH, STATUS_HEIGHT);
     507               
    495508                if (cstatus_vp[i] < 0)
    496509                        return;
     510               
    497511                vp_switch(cstatus_vp[i]);
    498512                set_rgb_color(0x202020, 0xffffff);
     
    502516        ic_pixmaps[CONS_SELECTED] =
    503517            make_pixmap(_binary_gfx_cons_selected_ppm_start,
    504             (int) &_binary_gfx_cons_selected_ppm_size);
     518            (size_t) &_binary_gfx_cons_selected_ppm_size);
    505519        ic_pixmaps[CONS_IDLE] =
    506520            make_pixmap(_binary_gfx_cons_idle_ppm_start,
    507             (int) &_binary_gfx_cons_idle_ppm_size);
     521            (size_t) &_binary_gfx_cons_idle_ppm_size);
    508522        ic_pixmaps[CONS_HAS_DATA] =
    509523            make_pixmap(_binary_gfx_cons_has_data_ppm_start,
    510             (int) &_binary_gfx_cons_has_data_ppm_size);
     524            (size_t) &_binary_gfx_cons_has_data_ppm_size);
    511525        ic_pixmaps[CONS_DISCONNECTED] =
    512526            make_pixmap(_binary_gfx_cons_idle_ppm_start,
    513             (int) &_binary_gfx_cons_idle_ppm_size);
     527            (size_t) &_binary_gfx_cons_idle_ppm_size);
    514528        ic_pixmaps[CONS_KERNEL] =
    515529            make_pixmap(_binary_gfx_cons_kernel_ppm_start,
    516             (int) &_binary_gfx_cons_kernel_ppm_size);
     530            (size_t) &_binary_gfx_cons_kernel_ppm_size);
    517531        ic_pixmaps[CONS_DISCONNECTED_SEL] = ic_pixmaps[CONS_SELECTED];
    518532       
    519533        make_anim();
    520534       
    521         use_gcons = 1;
     535        use_gcons = true;
    522536        console_state[0] = CONS_DISCONNECTED_SEL;
    523537        console_state[KERNEL_CONSOLE] = CONS_KERNEL;
     538       
    524539        gcons_redraw_console();
    525540}
  • uspace/srv/console/gcons.h

    rb0a91acb r424cd43  
    3333 */
    3434
    35 #ifndef _GCONS_H_
    36 #define _GCONS_H_
     35#ifndef GCONS_H_
     36#define GCONS_H_
     37
     38#include <sys/types.h>
    3739
    3840void gcons_init(int phone);
     41
    3942void gcons_redraw_console(void);
    40 void gcons_change_console(int consnum);
    41 void gcons_notify_char(int consnum);
     43void gcons_change_console(size_t index);
     44void gcons_notify_char(size_t index);
    4245void gcons_in_kernel(void);
    43 void gcons_notify_connect(int consnum);
    44 void gcons_notify_disconnect(int consnum);
    45 void gcons_mouse_move(int dx, int dy);
    46 int gcons_mouse_btn(int state);
     46
     47void gcons_notify_connect(size_t index);
     48void gcons_notify_disconnect(size_t index);
     49
     50void gcons_mouse_move(ssize_t dx, ssize_t dy);
     51int gcons_mouse_btn(bool state);
    4752
    4853#endif
  • uspace/srv/console/screenbuffer.c

    rb0a91acb r424cd43  
    3434
    3535#include <screenbuffer.h>
    36 #include <console/style.h>
     36#include <io/style.h>
    3737#include <malloc.h>
    3838#include <unistd.h>
     
    6767 *
    6868 */
    69 screenbuffer_t *screenbuffer_init(screenbuffer_t *scr, int size_x, int size_y)
     69screenbuffer_t *screenbuffer_init(screenbuffer_t *scr, size_t size_x, size_t size_y)
    7070{
    7171        scr->buffer = (keyfield_t *) malloc(sizeof(keyfield_t) * size_x * size_y);
     
    9191void screenbuffer_clear(screenbuffer_t *scr)
    9292{
    93         unsigned int i;
     93        size_t i;
    9494       
    9595        for (i = 0; i < (scr->size_x * scr->size_y); i++) {
     
    9999       
    100100        scr->top_line = 0;
     101        scr->position_x = 0;
    101102        scr->position_y = 0;
    102         scr->position_x = 0;
    103103}
    104104
     
    109109 *
    110110 */
    111 void screenbuffer_clear_line(screenbuffer_t *scr, unsigned int line)
     111void screenbuffer_clear_line(screenbuffer_t *scr, size_t line)
    112112{
    113         unsigned int i;
     113        size_t x;
    114114       
    115         for (i = 0; i < scr->size_x; i++) {
    116                 scr->buffer[i + line * scr->size_x].character = ' ';
    117                 scr->buffer[i + line * scr->size_x].attrs = scr->attrs;
     115        for (x = 0; x < scr->size_x; x++) {
     116                scr->buffer[x + line * scr->size_x].character = ' ';
     117                scr->buffer[x + line * scr->size_x].attrs = scr->attrs;
    118118        }
    119119}
     
    125125 *
    126126 */
    127 void screenbuffer_copy_buffer(screenbuffer_t *scr, keyfield_t *dest) 
     127void screenbuffer_copy_buffer(screenbuffer_t *scr, keyfield_t *dest)
    128128{
    129         unsigned int i;
     129        size_t i;
    130130       
    131         for (i = 0; i < scr->size_x * scr->size_y; i++)
     131        for (i = 0; i < (scr->size_x * scr->size_y); i++)
    132132                dest[i] = scr->buffer[i];
    133133}
     
    140140 *
    141141 */
    142 void screenbuffer_goto(screenbuffer_t *scr, unsigned int x, unsigned int y)
     142void screenbuffer_goto(screenbuffer_t *scr, size_t x, size_t y)
    143143{
    144144        scr->position_x = x % scr->size_x;
     
    153153 *
    154154 */
    155 void screenbuffer_set_style(screenbuffer_t *scr, int style)
     155void screenbuffer_set_style(screenbuffer_t *scr, uint8_t style)
    156156{
    157157        scr->attrs.t = at_style;
     
    166166 *
    167167 */
    168 void screenbuffer_set_color(screenbuffer_t *scr, unsigned int fg_color, unsigned int bg_color, unsigned int flags)
     168void screenbuffer_set_color(screenbuffer_t *scr, uint8_t fg_color, uint8_t bg_color, uint8_t flags)
    169169{
    170170        scr->attrs.t = at_idx;
     
    181181 *
    182182 */
    183 void screenbuffer_set_rgb_color(screenbuffer_t *scr, unsigned int fg_color, unsigned int bg_color)
     183void screenbuffer_set_rgb_color(screenbuffer_t *scr, uint32_t fg_color, uint32_t bg_color)
    184184{
    185185        scr->attrs.t = at_rgb;
  • uspace/srv/console/screenbuffer.h

    rb0a91acb r424cd43  
    3838#include <stdint.h>
    3939#include <sys/types.h>
     40#include <bool.h>
    4041
    41 #define DEFAULT_FOREGROUND 0x0       /**< default console foreground color */
    42 #define DEFAULT_BACKGROUND 0xf0f0f0  /**< default console background color */
     42#define DEFAULT_FOREGROUND  0x0       /**< default console foreground color */
     43#define DEFAULT_BACKGROUND  0xf0f0f0  /**< default console background color */
    4344
    4445typedef struct {
     
    7374typedef struct {
    7475        wchar_t character;  /**< Character itself */
    75         attrs_t attrs;      /**< Character`s attributes */
     76        attrs_t attrs;      /**< Character attributes */
    7677} keyfield_t;
    7778
     
    7980 */
    8081typedef struct {
    81         keyfield_t *buffer;               /**< Screen content - characters and
    82                                                their attributes (used as a circular buffer) */
    83         unsigned int size_x;              /**< Number of columns  */
    84         unsigned int size_y;              /**< Number of rows */
     82        keyfield_t *buffer;      /**< Screen content - characters and
     83                                      their attributes (used as a circular buffer) */
     84        size_t size_x;           /**< Number of columns  */
     85        size_t size_y;           /**< Number of rows */
    8586       
    8687        /** Coordinates of last printed character for determining cursor position */
    87         unsigned int position_x;
    88         unsigned int position_y;
     88        size_t position_x;
     89        size_t position_y;
    8990       
    90         attrs_t attrs;                    /**< Current attributes. */
    91         unsigned int top_line;            /**< Points to buffer[][] line that will
    92                                                be printed at screen as the first line */
    93         unsigned char is_cursor_visible;  /**< Cursor state - default is visible */
     91        attrs_t attrs;           /**< Current attributes. */
     92        size_t top_line;         /**< Points to buffer[][] line that will
     93                                      be printed at screen as the first line */
     94        bool is_cursor_visible;  /**< Cursor state - default is visible */
    9495} screenbuffer_t;
    9596
     
    106107 *
    107108 */
    108 static inline keyfield_t *get_field_at(screenbuffer_t *scr, unsigned int x, unsigned int y)
     109static inline keyfield_t *get_field_at(screenbuffer_t *scr, size_t x, size_t y)
    109110{
    110111        return scr->buffer + x + ((y + scr->top_line) % scr->size_y) * scr->size_x;
     
    139140
    140141void screenbuffer_putchar(screenbuffer_t *scr, wchar_t c);
    141 screenbuffer_t *screenbuffer_init(screenbuffer_t *scr, int size_x, int size_y);
     142screenbuffer_t *screenbuffer_init(screenbuffer_t *scr, size_t size_x, size_t size_y);
    142143
    143144void screenbuffer_clear(screenbuffer_t *scr);
    144 void screenbuffer_clear_line(screenbuffer_t *scr, unsigned int line);
     145void screenbuffer_clear_line(screenbuffer_t *scr, size_t line);
    145146void screenbuffer_copy_buffer(screenbuffer_t *scr, keyfield_t *dest);
    146 void screenbuffer_goto(screenbuffer_t *scr, unsigned int x, unsigned int y);
    147 void screenbuffer_set_style(screenbuffer_t *scr, int style);
    148 void screenbuffer_set_color(screenbuffer_t *scr, unsigned int fg_color,
    149     unsigned int bg_color, unsigned int attr);
    150 void screenbuffer_set_rgb_color(screenbuffer_t *scr, unsigned int fg_color,
    151     unsigned int bg_color);
     147void screenbuffer_goto(screenbuffer_t *scr, size_t x, size_t y);
     148void screenbuffer_set_style(screenbuffer_t *scr, uint8_t style);
     149void screenbuffer_set_color(screenbuffer_t *scr, uint8_t fg_color,
     150    uint8_t bg_color, uint8_t attr);
     151void screenbuffer_set_rgb_color(screenbuffer_t *scr, uint32_t fg_color,
     152    uint32_t bg_color);
    152153
    153154#endif
Note: See TracChangeset for help on using the changeset viewer.