Ignore:
File:
1 edited

Legend:

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

    rb366a6f4 rffa2c8ef  
    11/*
    22 * Copyright (c) 2006 Josef Cejka
    3  * Copyright (c) 2011 Jiri Svoboda
    43 * All rights reserved.
    54 *
     
    3534
    3635#include <libc.h>
    37 #include <ipc/input.h>
     36#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 <ns.h>
    42 #include <ns_obsolete.h>
     41#include <ipc/ns.h>
    4342#include <errno.h>
    44 #include <str_error.h>
    4543#include <ipc/console.h>
    4644#include <unistd.h>
    4745#include <async.h>
    48 #include <async_obsolete.h>
    4946#include <adt/fifo.h>
    5047#include <sys/mman.h>
     
    6461#include "keybuffer.h"
    6562
     63
    6664#define NAME       "console"
    6765#define NAMESPACE  "term"
    6866
    69 /** Session with the input server. */
    70 static async_sess_t *input_sess;
     67/** Phone to the keyboard driver. */
     68static int kbd_phone;
     69
     70/** Phone to the mouse driver. */
     71static int mouse_phone;
    7172
    7273/** Information about framebuffer */
     
    108109static FIBRIL_CONDVAR_INITIALIZE(input_cv);
    109110
    110 static FIBRIL_MUTEX_INITIALIZE(big_console_lock);
    111 
    112 static void console_serialize_start(void)
    113 {
    114         fibril_mutex_lock(&big_console_lock);
    115 }
    116 
    117 static void console_serialize_end(void)
    118 {
    119         fibril_mutex_unlock(&big_console_lock);
    120 }
    121 
    122111static void curs_visibility(bool visible)
    123112{
    124         async_obsolete_msg_1(fb_info.phone, FB_CURSOR_VISIBILITY, visible);
     113        async_msg_1(fb_info.phone, FB_CURSOR_VISIBILITY, visible);
    125114}
    126115
    127116static void curs_hide_sync(void)
    128117{
    129         async_obsolete_req_1_0(fb_info.phone, FB_CURSOR_VISIBILITY, false);
     118        async_req_1_0(fb_info.phone, FB_CURSOR_VISIBILITY, false);
    130119}
    131120
    132121static void curs_goto(sysarg_t x, sysarg_t y)
    133122{
    134         async_obsolete_msg_2(fb_info.phone, FB_CURSOR_GOTO, x, y);
     123        async_msg_2(fb_info.phone, FB_CURSOR_GOTO, x, y);
    135124}
    136125
    137126static void screen_clear(void)
    138127{
    139         async_obsolete_msg_0(fb_info.phone, FB_CLEAR);
     128        async_msg_0(fb_info.phone, FB_CLEAR);
    140129}
    141130
    142131static void screen_yield(void)
    143132{
    144         async_obsolete_req_0_0(fb_info.phone, FB_SCREEN_YIELD);
     133        async_req_0_0(fb_info.phone, FB_SCREEN_YIELD);
    145134}
    146135
    147136static void screen_reclaim(void)
    148137{
    149         async_obsolete_req_0_0(fb_info.phone, FB_SCREEN_RECLAIM);
    150 }
    151 
    152 static void input_yield(void)
    153 {
    154         async_exch_t *exch = async_exchange_begin(input_sess);
    155         if (exch == NULL) {
    156                 printf("%s: Failed starting exchange with input device.\n",
    157                     NAME);
    158                 return;
    159         }
    160        
    161         async_req_0_0(exch, INPUT_YIELD);
    162         async_exchange_end(exch);
    163 }
    164 
    165 static void input_reclaim(void)
    166 {
    167         async_exch_t *exch = async_exchange_begin(input_sess);
    168         if (exch == NULL) {
    169                 printf("%s: Failed starting exchange with input device.\n",
    170                     NAME);
    171                 return;
    172         }
    173        
    174         async_req_0_0(exch, INPUT_RECLAIM);
    175         async_exchange_end(exch);
     138        async_req_0_0(fb_info.phone, FB_SCREEN_RECLAIM);
     139}
     140
     141static void kbd_yield(void)
     142{
     143        async_req_0_0(kbd_phone, KBD_YIELD);
     144}
     145
     146static void kbd_reclaim(void)
     147{
     148        async_req_0_0(kbd_phone, KBD_RECLAIM);
    176149}
    177150
    178151static void set_style(uint8_t style)
    179152{
    180         async_obsolete_msg_1(fb_info.phone, FB_SET_STYLE, style);
     153        async_msg_1(fb_info.phone, FB_SET_STYLE, style);
    181154}
    182155
    183156static void set_color(uint8_t fgcolor, uint8_t bgcolor, uint8_t flags)
    184157{
    185         async_obsolete_msg_3(fb_info.phone, FB_SET_COLOR, fgcolor, bgcolor, flags);
     158        async_msg_3(fb_info.phone, FB_SET_COLOR, fgcolor, bgcolor, flags);
    186159}
    187160
    188161static void set_rgb_color(uint32_t fgcolor, uint32_t bgcolor)
    189162{
    190         async_obsolete_msg_2(fb_info.phone, FB_SET_RGB_COLOR, fgcolor, bgcolor);
     163        async_msg_2(fb_info.phone, FB_SET_RGB_COLOR, fgcolor, bgcolor);
    191164}
    192165
     
    243216                }
    244217               
    245                 async_obsolete_req_4_0(fb_info.phone, FB_DRAW_TEXT_DATA,
     218                async_req_4_0(fb_info.phone, FB_DRAW_TEXT_DATA,
    246219                    x0, y0, width, height);
    247220        }
     
    284257static void fb_putchar(wchar_t c, sysarg_t col, sysarg_t row)
    285258{
    286         async_obsolete_msg_3(fb_info.phone, FB_PUTCHAR, c, col, row);
     259        async_msg_3(fb_info.phone, FB_PUTCHAR, c, col, row);
    287260}
    288261
     
    333306               
    334307                if (cons == active_console)
    335                         async_obsolete_msg_1(fb_info.phone, FB_SCROLL, 1);
     308                        async_msg_1(fb_info.phone, FB_SCROLL, 1);
    336309        }
    337310       
     
    350323       
    351324        if (cons == kernel_console) {
    352                 console_serialize_start();
     325                async_serialize_start();
    353326                curs_hide_sync();
    354327                gcons_in_kernel();
    355328                screen_yield();
    356                 input_yield();
    357                 console_serialize_end();
    358                
    359                 if (console_kcon()) {
     329                kbd_yield();
     330                async_serialize_end();
     331               
     332                if (__SYSCALL0(SYS_DEBUG_ENABLE_CONSOLE)) {
    360333                        prev_console = active_console;
    361334                        active_console = kernel_console;
     
    365338       
    366339        if (cons != kernel_console) {
    367                 console_serialize_start();
     340                async_serialize_start();
    368341               
    369342                if (active_console == kernel_console) {
    370343                        screen_reclaim();
    371                         input_reclaim();
     344                        kbd_reclaim();
    372345                        gcons_redraw_console();
    373346                }
     
    392365                       
    393366                        /* This call can preempt, but we are already at the end */
    394                         rc = async_obsolete_req_4_0(fb_info.phone, FB_DRAW_TEXT_DATA,
     367                        rc = async_req_4_0(fb_info.phone, FB_DRAW_TEXT_DATA,
    395368                            0, 0, cons->scr.size_x,
    396369                            cons->scr.size_y);
     
    420393                curs_visibility(cons->scr.is_cursor_visible);
    421394               
    422                 console_serialize_end();
    423         }
    424 }
    425 
    426 /** Handler for input events */
    427 static void input_events(ipc_callid_t iid, ipc_call_t *icall, void *arg)
     395                async_serialize_end();
     396        }
     397}
     398
     399/** Handler for keyboard */
     400static void keyboard_events(ipc_callid_t iid, ipc_call_t *icall)
    428401{
    429402        /* Ignore parameters, the connection is already opened */
     
    433406               
    434407                int retval;
    435                 kbd_event_t ev;
    436                
    437                 if (!IPC_GET_IMETHOD(call)) {
     408                console_event_t ev;
     409               
     410                switch (IPC_GET_IMETHOD(call)) {
     411                case IPC_M_PHONE_HUNGUP:
    438412                        /* TODO: Handle hangup */
    439                         async_hangup(input_sess);
    440413                        return;
    441                 }
    442                
    443                 switch (IPC_GET_IMETHOD(call)) {
    444                 case INPUT_EVENT_KEY:
    445                         /* Got key press/release event */
     414                case KBD_EVENT:
     415                        /* Got event from keyboard driver. */
    446416                        retval = 0;
    447417                        ev.type = IPC_GET_ARG1(call);
     
    464434                        fibril_mutex_unlock(&input_mutex);
    465435                        break;
    466                 case INPUT_EVENT_MOVE:
    467                         /* Got pointer move event */
    468                         gcons_mouse_move((int) IPC_GET_ARG1(call),
    469                             (int) IPC_GET_ARG2(call));
    470                         retval = 0;
    471                         break;
    472                 case INPUT_EVENT_BUTTON:
    473                         /* Got pointer button press/release event */
     436                default:
     437                        retval = ENOENT;
     438                }
     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:
    474458                        if (IPC_GET_ARG1(call) == 1) {
    475459                                int newcon = gcons_mouse_btn((bool) IPC_GET_ARG2(call));
     
    479463                        retval = 0;
    480464                        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;
    481470                default:
    482471                        retval = ENOENT;
     
    498487        }
    499488       
    500         console_serialize_start();
     489        async_serialize_start();
    501490       
    502491        size_t off = 0;
     
    506495        }
    507496       
    508         console_serialize_end();
     497        async_serialize_end();
    509498       
    510499        gcons_notify_char(cons->index);
     
    532521       
    533522        size_t pos = 0;
    534         kbd_event_t ev;
     523        console_event_t ev;
    535524        fibril_mutex_lock(&input_mutex);
    536525       
     
    557546static void cons_get_event(console_t *cons, ipc_callid_t rid, ipc_call_t *request)
    558547{
    559         kbd_event_t ev;
     548        console_event_t ev;
    560549       
    561550        fibril_mutex_lock(&input_mutex);
     
    573562
    574563/** Default thread for new connections */
    575 static void client_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
     564static void client_connection(ipc_callid_t iid, ipc_call_t *icall)
    576565{
    577566        console_t *cons = NULL;
     
    601590        int rc;
    602591       
    603         console_serialize_start();
     592        async_serialize_start();
    604593        if (cons->refcount == 0)
    605594                gcons_notify_connect(cons->index);
     
    611600       
    612601        while (true) {
    613                 console_serialize_end();
     602                async_serialize_end();
    614603                callid = async_get_call(&call);
    615                 console_serialize_start();
     604                async_serialize_start();
    616605               
    617606                arg1 = 0;
     
    619608                arg3 = 0;
    620609               
    621                 if (!IPC_GET_IMETHOD(call)) {
     610                switch (IPC_GET_IMETHOD(call)) {
     611                case IPC_M_PHONE_HUNGUP:
    622612                        cons->refcount--;
    623613                        if (cons->refcount == 0)
    624614                                gcons_notify_disconnect(cons->index);
    625                         console_serialize_end();
    626615                        return;
    627                 }
    628                
    629                 switch (IPC_GET_IMETHOD(call)) {
    630616                case VFS_OUT_READ:
    631                         console_serialize_end();
     617                        async_serialize_end();
    632618                        cons_read(cons, callid, &call);
    633                         console_serialize_start();
     619                        async_serialize_start();
    634620                        continue;
    635621                case VFS_OUT_WRITE:
    636                         console_serialize_end();
     622                        async_serialize_end();
    637623                        cons_write(cons, callid, &call);
    638                         console_serialize_start();
     624                        async_serialize_start();
    639625                        continue;
    640626                case VFS_OUT_SYNC:
    641627                        fb_pending_flush();
    642628                        if (cons == active_console) {
    643                                 async_obsolete_req_0_0(fb_info.phone, FB_FLUSH);
     629                                async_req_0_0(fb_info.phone, FB_FLUSH);
    644630                                curs_goto(cons->scr.position_x, cons->scr.position_y);
    645631                        }
     
    648634                        /* Send message to fb */
    649635                        if (cons == active_console)
    650                                 async_obsolete_msg_0(fb_info.phone, FB_CLEAR);
     636                                async_msg_0(fb_info.phone, FB_CLEAR);
    651637                       
    652638                        screenbuffer_clear(&cons->scr);
     
    707693                        break;
    708694                case CONSOLE_GET_EVENT:
    709                         console_serialize_end();
     695                        async_serialize_end();
    710696                        cons_get_event(cons, callid, &call);
    711                         console_serialize_start();
     697                        async_serialize_start();
    712698                        continue;
     699                case CONSOLE_KCON_ENABLE:
     700                        change_console(kernel_console);
     701                        break;
    713702                }
    714703                async_answer_3(callid, EOK, arg1, arg2, arg3);
     
    721710}
    722711
    723 static async_sess_t *connect_input(const char *dev_path)
    724 {
    725         async_sess_t *sess;
    726         async_exch_t *exch;
    727         devmap_handle_t handle;
    728        
    729         int rc = devmap_device_get_handle(dev_path, &handle, 0);
    730         if (rc == EOK) {
    731                 sess = devmap_device_connect(EXCHANGE_ATOMIC, handle, 0);
    732                 if (sess == NULL) {
    733                         printf("%s: Failed to connect to input server\n", NAME);
    734                         return NULL;
    735                 }
    736         } else {
    737                 return NULL;
    738         }
    739        
    740         exch = async_exchange_begin(sess);
    741         if (exch == NULL) {
    742                 printf("%s: Failed to create callback from input server.\n", NAME);
    743                 return NULL;
     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);
     722        if (kbd_phone < 0) {
     723                printf(NAME ": Failed to connect to input device\n");
     724                return false;
    744725        }
    745726       
    746727        /* NB: The callback connection is slotted for removal */
    747         rc = async_connect_to_me(exch, 0, 0, 0, input_events, NULL);
    748 
    749         async_exchange_end(exch);
    750 
    751         if (rc != EOK) {
    752                 async_hangup(sess);
    753                 printf("%s: Failed to create callback from input server (%s).\n",
    754                     NAME, str_error(rc));
    755                 return NULL;
    756         }
    757        
    758         return sess;
    759 }
    760 
    761 static bool console_srv_init(char *input_dev)
    762 {
    763         /* Connect to input server */
    764         input_sess = connect_input(input_dev);
    765         if (input_sess == NULL)
     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");
    766731                return false;
     732        }
     733       
     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:
    767757       
    768758        /* Connect to framebuffer driver */
    769         fb_info.phone = service_obsolete_connect_blocking(SERVICE_VIDEO, 0, 0);
     759        fb_info.phone = service_connect_blocking(SERVICE_VIDEO, 0, 0);
    770760        if (fb_info.phone < 0) {
    771                 printf("%s: Failed to connect to video service\n", NAME);
    772                 return false;
     761                printf(NAME ": Failed to connect to video service\n");
     762                return -1;
    773763        }
    774764       
     
    776766        int rc = devmap_driver_register(NAME, client_connection);
    777767        if (rc < 0) {
    778                 printf("%s: Unable to register driver (%d)\n", NAME, rc);
     768                printf(NAME ": Unable to register driver (%d)\n", rc);
    779769                return false;
    780770        }
     
    784774       
    785775        /* Synchronize, the gcons could put something in queue */
    786         async_obsolete_req_0_0(fb_info.phone, FB_FLUSH);
    787         async_obsolete_req_0_2(fb_info.phone, FB_GET_CSIZE, &fb_info.cols, &fb_info.rows);
    788         async_obsolete_req_0_1(fb_info.phone, FB_GET_COLOR_CAP, &fb_info.color_cap);
     776        async_req_0_0(fb_info.phone, FB_FLUSH);
     777        async_req_0_2(fb_info.phone, FB_GET_CSIZE, &fb_info.cols, &fb_info.rows);
     778        async_req_0_1(fb_info.phone, FB_GET_COLOR_CAP, &fb_info.color_cap);
    789779       
    790780        /* Set up shared memory buffer. */
     
    797787       
    798788        if (interbuffer) {
    799                 if (async_obsolete_share_out_start(fb_info.phone, interbuffer,
     789                if (async_share_out_start(fb_info.phone, interbuffer,
    800790                    AS_AREA_READ) != EOK) {
    801791                        as_area_destroy(interbuffer);
     
    812802                        if (screenbuffer_init(&consoles[i].scr,
    813803                            fb_info.cols, fb_info.rows) == NULL) {
    814                                 printf("%s: Unable to allocate screen buffer %zu\n", NAME, i);
     804                                printf(NAME ": Unable to allocate screen buffer %zu\n", i);
    815805                                return false;
    816806                        }
     
    824814                       
    825815                        if (devmap_device_register(vc, &consoles[i].devmap_handle) != EOK) {
    826                                 printf("%s: Unable to register device %s\n", NAME, vc);
     816                                printf(NAME ": Unable to register device %s\n", vc);
    827817                                return false;
    828818                        }
     
    830820        }
    831821       
     822        /* Disable kernel output to the console */
     823        __SYSCALL0(SYS_DEBUG_DISABLE_CONSOLE);
     824       
    832825        /* Initialize the screen */
    833         console_serialize_start();
     826        async_serialize_start();
    834827        gcons_redraw_console();
    835828        set_style(STYLE_NORMAL);
     
    837830        curs_goto(0, 0);
    838831        curs_visibility(active_console->scr.is_cursor_visible);
    839         console_serialize_end();
     832        async_serialize_end();
    840833       
    841834        /* Receive kernel notifications */
    842835        async_set_interrupt_received(interrupt_received);
    843836        if (event_subscribe(EVENT_KCONSOLE, 0) != EOK)
    844                 printf("%s: Error registering kconsole notifications\n", NAME);
     837                printf(NAME ": Error registering kconsole notifications\n");
    845838       
    846839        return true;
     
    849842static void usage(void)
    850843{
    851         printf("Usage: console <input_dev>\n");
     844        printf("Usage: console <input>\n");
    852845}
    853846
     
    861854        printf(NAME ": HelenOS Console service\n");
    862855       
    863         if (!console_srv_init(argv[1]))
     856        if (!console_init(argv[1]))
    864857                return -1;
    865858       
Note: See TracChangeset for help on using the changeset viewer.