Changeset 04803bf in mainline for uspace/srv/hid/console/console.c


Ignore:
Timestamp:
2011-03-21T22:00:17Z (15 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
143932e3
Parents:
b50b5af2 (diff), 7308e84 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge mainline changes (needs fixes).

File:
1 moved

Legend:

Unmodified
Added
Removed
  • uspace/srv/hid/console/console.c

    rb50b5af2 r04803bf  
    3434
    3535#include <libc.h>
    36 #include <ipc/ipc.h>
    3736#include <ipc/kbd.h>
    3837#include <io/keycode.h>
     38#include <ipc/mouse.h>
    3939#include <ipc/fb.h>
    4040#include <ipc/services.h>
     41#include <ipc/ns.h>
    4142#include <errno.h>
    42 #include <keybuffer.h>
    4343#include <ipc/console.h>
    4444#include <unistd.h>
     
    4747#include <sys/mman.h>
    4848#include <stdio.h>
    49 #include <string.h>
     49#include <str.h>
    5050#include <sysinfo.h>
    5151#include <event.h>
    5252#include <devmap.h>
    53 #include <fibril_sync.h>
     53#include <fcntl.h>
     54#include <vfs/vfs.h>
     55#include <fibril_synch.h>
     56#include <io/style.h>
     57#include <io/screenbuffer.h>
    5458
    5559#include "console.h"
    5660#include "gcons.h"
    57 #include "screenbuffer.h"
    58 
    59 #define NAME  "console"
    60 
    61 #define MAX_DEVICE_NAME  32
     61#include "keybuffer.h"
     62
     63
     64#define NAME       "console"
     65#define NAMESPACE  "term"
    6266
    6367/** Phone to the keyboard driver. */
    6468static int kbd_phone;
    6569
     70/** Phone to the mouse driver. */
     71static int mouse_phone;
     72
    6673/** Information about framebuffer */
    6774struct {
    68         int phone;      /**< Framebuffer phone */
    69         ipcarg_t cols;  /**< Framebuffer columns */
    70         ipcarg_t rows;  /**< Framebuffer rows */
    71         int color_cap;  /**< Color capabilities (FB_CCAP_xxx) */
     75        int phone;           /**< Framebuffer phone */
     76        sysarg_t cols;       /**< Framebuffer columns */
     77        sysarg_t rows;       /**< Framebuffer rows */
     78        sysarg_t color_cap;  /**< Color capabilities (FB_CCAP_xxx) */
    7279} fb_info;
    7380
     
    7582        size_t index;             /**< Console index */
    7683        size_t refcount;          /**< Connection reference count */
    77         dev_handle_t dev_handle;  /**< Device handle */
     84        devmap_handle_t devmap_handle;  /**< Device handle */
    7885        keybuffer_t keybuffer;    /**< Buffer for incoming keys. */
    7986        screenbuffer_t scr;       /**< Screenbuffer for saving screen
     
    94101/** Information on row-span yet unsent to FB driver. */
    95102struct {
    96         size_t col;  /**< Leftmost column of the span. */
    97         size_t row;  /**< Row where the span lies. */
    98         size_t cnt;  /**< Width of the span. */
     103        sysarg_t col;  /**< Leftmost column of the span. */
     104        sysarg_t row;  /**< Row where the span lies. */
     105        sysarg_t cnt;  /**< Width of the span. */
    99106} fb_pending;
    100107
     
    109116static void curs_hide_sync(void)
    110117{
    111         ipc_call_sync_1_0(fb_info.phone, FB_CURSOR_VISIBILITY, false);
    112 }
    113 
    114 static void curs_goto(size_t x, size_t y)
     118        async_req_1_0(fb_info.phone, FB_CURSOR_VISIBILITY, false);
     119}
     120
     121static void curs_goto(sysarg_t x, sysarg_t y)
    115122{
    116123        async_msg_2(fb_info.phone, FB_CURSOR_GOTO, x, y);
     
    124131static void screen_yield(void)
    125132{
    126         ipc_call_sync_0_0(fb_info.phone, FB_SCREEN_YIELD);
     133        async_req_0_0(fb_info.phone, FB_SCREEN_YIELD);
    127134}
    128135
    129136static void screen_reclaim(void)
    130137{
    131         ipc_call_sync_0_0(fb_info.phone, FB_SCREEN_RECLAIM);
     138        async_req_0_0(fb_info.phone, FB_SCREEN_RECLAIM);
    132139}
    133140
    134141static void kbd_yield(void)
    135142{
    136         ipc_call_sync_0_0(kbd_phone, KBD_YIELD);
     143        async_req_0_0(kbd_phone, KBD_YIELD);
    137144}
    138145
    139146static void kbd_reclaim(void)
    140147{
    141         ipc_call_sync_0_0(kbd_phone, KBD_RECLAIM);
    142 }
    143 
    144 static void set_style(int style)
     148        async_req_0_0(kbd_phone, KBD_RECLAIM);
     149}
     150
     151static void set_style(uint8_t style)
    145152{
    146153        async_msg_1(fb_info.phone, FB_SET_STYLE, style);
    147154}
    148155
    149 static void set_color(int fgcolor, int bgcolor, int flags)
     156static void set_color(uint8_t fgcolor, uint8_t bgcolor, uint8_t flags)
    150157{
    151158        async_msg_3(fb_info.phone, FB_SET_COLOR, fgcolor, bgcolor, flags);
    152159}
    153160
    154 static void set_rgb_color(int fgcolor, int bgcolor)
     161static void set_rgb_color(uint32_t fgcolor, uint32_t bgcolor)
    155162{
    156163        async_msg_2(fb_info.phone, FB_SET_RGB_COLOR, fgcolor, bgcolor);
     
    173180}
    174181
    175 static int ccap_fb_to_con(int ccap_fb, int *ccap_con)
     182static int ccap_fb_to_con(sysarg_t ccap_fb, sysarg_t *ccap_con)
    176183{
    177184        switch (ccap_fb) {
    178         case FB_CCAP_NONE: *ccap_con = CONSOLE_CCAP_NONE; break;
    179         case FB_CCAP_STYLE: *ccap_con = CONSOLE_CCAP_STYLE; break;
    180         case FB_CCAP_INDEXED: *ccap_con = CONSOLE_CCAP_INDEXED; break;
    181         case FB_CCAP_RGB: *ccap_con = CONSOLE_CCAP_RGB; break;
    182         default: return EINVAL;
    183         }
    184 
     185        case FB_CCAP_NONE:
     186                *ccap_con = CONSOLE_CCAP_NONE;
     187                break;
     188        case FB_CCAP_STYLE:
     189                *ccap_con = CONSOLE_CCAP_STYLE;
     190                break;
     191        case FB_CCAP_INDEXED:
     192                *ccap_con = CONSOLE_CCAP_INDEXED;
     193                break;
     194        case FB_CCAP_RGB:
     195                *ccap_con = CONSOLE_CCAP_RGB;
     196                break;
     197        default:
     198                return EINVAL;
     199        }
     200       
    185201        return EOK;
    186202}
    187203
    188204/** Send an area of screenbuffer to the FB driver. */
    189 static void fb_update_area(console_t *cons, ipcarg_t x0, ipcarg_t y0, ipcarg_t width, ipcarg_t height)
     205static void fb_update_area(console_t *cons, sysarg_t x0, sysarg_t y0, sysarg_t width, sysarg_t height)
    190206{
    191207        if (interbuffer) {
    192                 ipcarg_t x;
    193                 ipcarg_t y;
     208                sysarg_t x;
     209                sysarg_t y;
    194210               
    195211                for (y = 0; y < height; y++) {
     
    221237 *
    222238 */
    223 static void cell_mark_changed(size_t col, size_t row)
     239static void cell_mark_changed(sysarg_t col, sysarg_t row)
    224240{
    225241        if (fb_pending.cnt != 0) {
     
    239255
    240256/** Print a character to the active VC with buffering. */
    241 static void fb_putchar(wchar_t c, ipcarg_t col, ipcarg_t row)
     257static void fb_putchar(wchar_t c, sysarg_t col, sysarg_t row)
    242258{
    243259        async_msg_3(fb_info.phone, FB_PUTCHAR, c, col, row);
     
    248264{
    249265        bool flush_cursor = false;
    250 
     266       
    251267        switch (ch) {
    252268        case '\n':
     
    292308                        async_msg_1(fb_info.phone, FB_SCROLL, 1);
    293309        }
    294 
     310       
    295311        if (cons == active_console && flush_cursor)
    296312                curs_goto(cons->scr.position_x, cons->scr.position_y);
     
    322338       
    323339        if (cons != kernel_console) {
    324                 size_t x;
    325                 size_t y;
    326                 int rc = 0;
    327                
    328340                async_serialize_start();
    329341               
     
    339351                set_attrs(&cons->scr.attrs);
    340352                curs_visibility(false);
     353               
     354                sysarg_t x;
     355                sysarg_t y;
     356                int rc = 0;
     357               
    341358                if (interbuffer) {
    342359                        for (y = 0; y < cons->scr.size_y; y++) {
     
    385402        /* Ignore parameters, the connection is already opened */
    386403        while (true) {
    387                
    388404                ipc_call_t call;
    389405                ipc_callid_t callid = async_get_call(&call);
     
    392408                console_event_t ev;
    393409               
    394                 switch (IPC_GET_METHOD(call)) {
     410                switch (IPC_GET_IMETHOD(call)) {
    395411                case IPC_M_PHONE_HUNGUP:
    396412                        /* TODO: Handle hangup */
     
    421437                        retval = ENOENT;
    422438                }
    423                 ipc_answer_0(callid, retval);
     439                async_answer_0(callid, retval);
     440        }
     441}
     442
     443/** Handler for mouse events */
     444static void mouse_events(ipc_callid_t iid, ipc_call_t *icall)
     445{
     446        /* Ignore parameters, the connection is already opened */
     447        while (true) {
     448                ipc_call_t call;
     449                ipc_callid_t callid = async_get_call(&call);
     450               
     451                int retval;
     452               
     453                switch (IPC_GET_IMETHOD(call)) {
     454                case IPC_M_PHONE_HUNGUP:
     455                        /* TODO: Handle hangup */
     456                        return;
     457                case MEVENT_BUTTON:
     458                        if (IPC_GET_ARG1(call) == 1) {
     459                                int newcon = gcons_mouse_btn((bool) IPC_GET_ARG2(call));
     460                                if (newcon != -1)
     461                                        change_console(&consoles[newcon]);
     462                        }
     463                        retval = 0;
     464                        break;
     465                case MEVENT_MOVE:
     466                        gcons_mouse_move((int) IPC_GET_ARG1(call),
     467                            (int) IPC_GET_ARG2(call));
     468                        retval = 0;
     469                        break;
     470                default:
     471                        retval = ENOENT;
     472                }
     473
     474                async_answer_0(callid, retval);
    424475        }
    425476}
     
    427478static void cons_write(console_t *cons, ipc_callid_t rid, ipc_call_t *request)
    428479{
    429         ipc_callid_t callid;
     480        void *buf;
    430481        size_t size;
    431         if (!ipc_data_write_receive(&callid, &size)) {
    432                 ipc_answer_0(callid, EINVAL);
    433                 ipc_answer_0(rid, EINVAL);
     482        int rc = async_data_write_accept(&buf, false, 0, 0, 0, &size);
     483       
     484        if (rc != EOK) {
     485                async_answer_0(rid, rc);
    434486                return;
    435487        }
    436        
    437         char *buf = (char *) malloc(size);
    438         if (buf == NULL) {
    439                 ipc_answer_0(callid, ENOMEM);
    440                 ipc_answer_0(rid, ENOMEM);
    441                 return;
    442         }
    443        
    444         (void) ipc_data_write_finalize(callid, buf, size);
    445488       
    446489        async_serialize_start();
     
    455498       
    456499        gcons_notify_char(cons->index);
    457         ipc_answer_1(rid, EOK, size);
     500        async_answer_1(rid, EOK, size);
    458501       
    459502        free(buf);
     
    464507        ipc_callid_t callid;
    465508        size_t size;
    466         if (!ipc_data_read_receive(&callid, &size)) {
    467                 ipc_answer_0(callid, EINVAL);
    468                 ipc_answer_0(rid, EINVAL);
     509        if (!async_data_read_receive(&callid, &size)) {
     510                async_answer_0(callid, EINVAL);
     511                async_answer_0(rid, EINVAL);
    469512                return;
    470513        }
     
    472515        char *buf = (char *) malloc(size);
    473516        if (buf == NULL) {
    474                 ipc_answer_0(callid, ENOMEM);
    475                 ipc_answer_0(rid, ENOMEM);
     517                async_answer_0(callid, ENOMEM);
     518                async_answer_0(rid, ENOMEM);
    476519                return;
    477520        }
     
    480523        console_event_t ev;
    481524        fibril_mutex_lock(&input_mutex);
     525       
    482526recheck:
    483527        while ((keybuffer_pop(&cons->keybuffer, &ev)) && (pos < size)) {
     
    489533       
    490534        if (pos == size) {
    491                 (void) ipc_data_read_finalize(callid, buf, size);
    492                 ipc_answer_1(rid, EOK, size);
     535                (void) async_data_read_finalize(callid, buf, size);
     536                async_answer_1(rid, EOK, size);
    493537                free(buf);
    494538        } else {
     
    496540                goto recheck;
    497541        }
     542       
    498543        fibril_mutex_unlock(&input_mutex);
    499544}
     
    502547{
    503548        console_event_t ev;
    504 
     549       
    505550        fibril_mutex_lock(&input_mutex);
     551       
    506552recheck:
    507553        if (keybuffer_pop(&cons->keybuffer, &ev)) {
    508                 ipc_answer_4(rid, EOK, ev.type, ev.key, ev.mods, ev.c);
     554                async_answer_4(rid, EOK, ev.type, ev.key, ev.mods, ev.c);
    509555        } else {
    510556                fibril_condvar_wait(&input_cv, &input_mutex);
    511557                goto recheck;
    512558        }
     559       
    513560        fibril_mutex_unlock(&input_mutex);
    514561}
     
    524571                        continue;
    525572               
    526                 if (consoles[i].dev_handle == (dev_handle_t) IPC_GET_ARG1(*icall)) {
     573                if (consoles[i].devmap_handle == (devmap_handle_t) IPC_GET_ARG1(*icall)) {
    527574                        cons = &consoles[i];
    528575                        break;
     
    531578       
    532579        if (cons == NULL) {
    533                 ipc_answer_0(iid, ENOENT);
     580                async_answer_0(iid, ENOENT);
    534581                return;
    535582        }
     
    537584        ipc_callid_t callid;
    538585        ipc_call_t call;
    539         ipcarg_t arg1;
    540         ipcarg_t arg2;
    541         ipcarg_t arg3;
    542 
    543         int cons_ccap;
     586        sysarg_t arg1;
     587        sysarg_t arg2;
     588        sysarg_t arg3;
     589       
    544590        int rc;
    545591       
     
    551597       
    552598        /* Accept the connection */
    553         ipc_answer_0(iid, EOK);
     599        async_answer_0(iid, EOK);
    554600       
    555601        while (true) {
     
    562608                arg3 = 0;
    563609               
    564                 switch (IPC_GET_METHOD(call)) {
     610                switch (IPC_GET_IMETHOD(call)) {
    565611                case IPC_M_PHONE_HUNGUP:
    566612                        cons->refcount--;
     
    582628                        if (cons == active_console) {
    583629                                async_req_0_0(fb_info.phone, FB_FLUSH);
    584                                
    585630                                curs_goto(cons->scr.position_x, cons->scr.position_y);
    586631                        }
     
    601646                                    IPC_GET_ARG2(call));
    602647                        break;
     648                case CONSOLE_GET_POS:
     649                        arg1 = cons->scr.position_x;
     650                        arg2 = cons->scr.position_y;
     651                        break;
    603652                case CONSOLE_GET_SIZE:
    604653                        arg1 = fb_info.cols;
     
    606655                        break;
    607656                case CONSOLE_GET_COLOR_CAP:
    608                         rc = ccap_fb_to_con(fb_info.color_cap, &cons_ccap);
     657                        rc = ccap_fb_to_con(fb_info.color_cap, &arg1);
    609658                        if (rc != EOK) {
    610                                 ipc_answer_0(callid, rc);
     659                                async_answer_0(callid, rc);
    611660                                continue;
    612661                        }
    613                         arg1 = cons_ccap;
    614662                        break;
    615663                case CONSOLE_SET_STYLE:
     
    653701                        break;
    654702                }
    655                 ipc_answer_3(callid, EOK, arg1, arg2, arg3);
     703                async_answer_3(callid, EOK, arg1, arg2, arg3);
    656704        }
    657705}
     
    662710}
    663711
    664 static bool console_init(void)
    665 {
    666         ipcarg_t color_cap;
    667 
    668         /* Connect to keyboard driver */
    669         kbd_phone = ipc_connect_me_to_blocking(PHONE_NS, SERVICE_KEYBOARD, 0, 0);
     712static bool console_init(char *input)
     713{
     714        /* Connect to input device */
     715        int input_fd = open(input, O_RDONLY);
     716        if (input_fd < 0) {
     717                printf(NAME ": Failed opening %s\n", input);
     718                return false;
     719        }
     720       
     721        kbd_phone = fd_phone(input_fd);
    670722        if (kbd_phone < 0) {
    671                 printf(NAME ": Failed to connect to keyboard service\n");
     723                printf(NAME ": Failed to connect to input device\n");
    672724                return false;
    673725        }
    674726       
    675         ipcarg_t phonehash;
    676         if (ipc_connect_to_me(kbd_phone, SERVICE_CONSOLE, 0, 0, &phonehash) != 0) {
    677                 printf(NAME ": Failed to create callback from keyboard service\n");
     727        /* NB: The callback connection is slotted for removal */
     728        if (async_connect_to_me(kbd_phone, SERVICE_CONSOLE, 0, 0, keyboard_events)
     729            != 0) {
     730                printf(NAME ": Failed to create callback from input device\n");
    678731                return false;
    679732        }
    680733       
    681         async_new_connection(phonehash, 0, NULL, keyboard_events);
    682 
     734        /* Connect to mouse device */
     735        mouse_phone = -1;
     736        int mouse_fd = open("/dev/hid_in/mouse", O_RDONLY);
     737       
     738        if (mouse_fd < 0) {
     739                printf(NAME ": Notice - failed opening %s\n", "/dev/hid_in/mouse");
     740                goto skip_mouse;
     741        }
     742       
     743        mouse_phone = fd_phone(mouse_fd);
     744        if (mouse_phone < 0) {
     745                printf(NAME ": Failed to connect to mouse device\n");
     746                goto skip_mouse;
     747        }
     748       
     749        if (async_connect_to_me(mouse_phone, SERVICE_CONSOLE, 0, 0, mouse_events)
     750            != 0) {
     751                printf(NAME ": Failed to create callback from mouse device\n");
     752                mouse_phone = -1;
     753                goto skip_mouse;
     754        }
     755       
     756skip_mouse:
     757       
    683758        /* Connect to framebuffer driver */
    684         fb_info.phone = ipc_connect_me_to_blocking(PHONE_NS, SERVICE_VIDEO, 0, 0);
     759        fb_info.phone = service_connect_blocking(SERVICE_VIDEO, 0, 0);
    685760        if (fb_info.phone < 0) {
    686761                printf(NAME ": Failed to connect to video service\n");
     
    701776        async_req_0_0(fb_info.phone, FB_FLUSH);
    702777        async_req_0_2(fb_info.phone, FB_GET_CSIZE, &fb_info.cols, &fb_info.rows);
    703         async_req_0_1(fb_info.phone, FB_GET_COLOR_CAP, &color_cap);
    704         fb_info.color_cap = color_cap;
     778        async_req_0_1(fb_info.phone, FB_GET_COLOR_CAP, &fb_info.color_cap);
    705779       
    706780        /* Set up shared memory buffer. */
     
    713787       
    714788        if (interbuffer) {
    715                 if (ipc_share_out_start(fb_info.phone, interbuffer,
     789                if (async_share_out_start(fb_info.phone, interbuffer,
    716790                    AS_AREA_READ) != EOK) {
    717791                        as_area_destroy(interbuffer);
     
    728802                        if (screenbuffer_init(&consoles[i].scr,
    729803                            fb_info.cols, fb_info.rows) == NULL) {
    730                                 printf(NAME ": Unable to allocate screen buffer %u\n", i);
     804                                printf(NAME ": Unable to allocate screen buffer %zu\n", i);
    731805                                return false;
    732806                        }
     
    736810                        consoles[i].refcount = 0;
    737811                       
    738                         char vc[MAX_DEVICE_NAME];
    739                         snprintf(vc, MAX_DEVICE_NAME, "vc%u", i);
     812                        char vc[DEVMAP_NAME_MAXLEN + 1];
     813                        snprintf(vc, DEVMAP_NAME_MAXLEN, "%s/vc%zu", NAMESPACE, i);
    740814                       
    741                         if (devmap_device_register(vc, &consoles[i].dev_handle) != EOK) {
    742                                 devmap_hangup_phone(DEVMAP_DRIVER);
     815                        if (devmap_device_register(vc, &consoles[i].devmap_handle) != EOK) {
    743816                                printf(NAME ": Unable to register device %s\n", vc);
    744817                                return false;
     
    753826        async_serialize_start();
    754827        gcons_redraw_console();
    755         set_rgb_color(DEFAULT_FOREGROUND, DEFAULT_BACKGROUND);
     828        set_style(STYLE_NORMAL);
    756829        screen_clear();
    757830        curs_goto(0, 0);
     
    760833       
    761834        /* Receive kernel notifications */
     835        async_set_interrupt_received(interrupt_received);
    762836        if (event_subscribe(EVENT_KCONSOLE, 0) != EOK)
    763837                printf(NAME ": Error registering kconsole notifications\n");
    764838       
    765         async_set_interrupt_received(interrupt_received);
    766        
    767839        return true;
    768840}
    769841
     842static void usage(void)
     843{
     844        printf("Usage: console <input>\n");
     845}
     846
    770847int main(int argc, char *argv[])
    771848{
     849        if (argc < 2) {
     850                usage();
     851                return -1;
     852        }
     853       
    772854        printf(NAME ": HelenOS Console service\n");
    773855       
    774         if (!console_init())
     856        if (!console_init(argv[1]))
    775857                return -1;
    776858       
Note: See TracChangeset for help on using the changeset viewer.