Changeset c028b22 in mainline for uspace/srv/hid/console/console.c


Ignore:
Timestamp:
2011-07-08T17:01:01Z (13 years ago)
Author:
Martin Sucha <sucha14@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
cc1a727
Parents:
4e36219 (diff), 026793d (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

File:
1 edited

Legend:

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

    r4e36219 rc028b22  
    11/*
    22 * Copyright (c) 2006 Josef Cejka
     3 * Copyright (c) 2011 Jiri Svoboda
    34 * All rights reserved.
    45 *
     
    3435
    3536#include <libc.h>
    36 #include <ipc/kbd.h>
     37#include <ipc/input.h>
    3738#include <io/keycode.h>
    38 #include <ipc/mouse.h>
    3939#include <ipc/fb.h>
    4040#include <ipc/services.h>
    41 #include <ipc/ns.h>
     41#include <ns.h>
     42#include <ns_obsolete.h>
    4243#include <errno.h>
     44#include <str_error.h>
    4345#include <ipc/console.h>
    4446#include <unistd.h>
    4547#include <async.h>
     48#include <async_obsolete.h>
    4649#include <adt/fifo.h>
    4750#include <sys/mman.h>
     
    6164#include "keybuffer.h"
    6265
    63 
    6466#define NAME       "console"
    6567#define NAMESPACE  "term"
    6668
    67 /** Phone to the keyboard driver. */
    68 static int kbd_phone;
    69 
    70 /** Phone to the mouse driver. */
    71 static int mouse_phone;
     69/** Session with the input server. */
     70static async_sess_t *input_sess;
    7271
    7372/** Information about framebuffer */
     
    109108static FIBRIL_CONDVAR_INITIALIZE(input_cv);
    110109
     110static FIBRIL_MUTEX_INITIALIZE(big_console_lock);
     111
     112static void console_serialize_start(void)
     113{
     114        fibril_mutex_lock(&big_console_lock);
     115}
     116
     117static void console_serialize_end(void)
     118{
     119        fibril_mutex_unlock(&big_console_lock);
     120}
     121
    111122static void curs_visibility(bool visible)
    112123{
    113         async_msg_1(fb_info.phone, FB_CURSOR_VISIBILITY, visible);
     124        async_obsolete_msg_1(fb_info.phone, FB_CURSOR_VISIBILITY, visible);
    114125}
    115126
    116127static void curs_hide_sync(void)
    117128{
    118         async_req_1_0(fb_info.phone, FB_CURSOR_VISIBILITY, false);
     129        async_obsolete_req_1_0(fb_info.phone, FB_CURSOR_VISIBILITY, false);
    119130}
    120131
    121132static void curs_goto(sysarg_t x, sysarg_t y)
    122133{
    123         async_msg_2(fb_info.phone, FB_CURSOR_GOTO, x, y);
     134        async_obsolete_msg_2(fb_info.phone, FB_CURSOR_GOTO, x, y);
    124135}
    125136
    126137static void screen_clear(void)
    127138{
    128         async_msg_0(fb_info.phone, FB_CLEAR);
     139        async_obsolete_msg_0(fb_info.phone, FB_CLEAR);
    129140}
    130141
    131142static void screen_yield(void)
    132143{
    133         async_req_0_0(fb_info.phone, FB_SCREEN_YIELD);
     144        async_obsolete_req_0_0(fb_info.phone, FB_SCREEN_YIELD);
    134145}
    135146
    136147static void screen_reclaim(void)
    137148{
    138         async_req_0_0(fb_info.phone, FB_SCREEN_RECLAIM);
    139 }
    140 
    141 static void kbd_yield(void)
    142 {
    143         async_req_0_0(kbd_phone, KBD_YIELD);
    144 }
    145 
    146 static void kbd_reclaim(void)
    147 {
    148         async_req_0_0(kbd_phone, KBD_RECLAIM);
     149        async_obsolete_req_0_0(fb_info.phone, FB_SCREEN_RECLAIM);
     150}
     151
     152static 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
     165static 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);
    149176}
    150177
    151178static void set_style(uint8_t style)
    152179{
    153         async_msg_1(fb_info.phone, FB_SET_STYLE, style);
     180        async_obsolete_msg_1(fb_info.phone, FB_SET_STYLE, style);
    154181}
    155182
    156183static void set_color(uint8_t fgcolor, uint8_t bgcolor, uint8_t flags)
    157184{
    158         async_msg_3(fb_info.phone, FB_SET_COLOR, fgcolor, bgcolor, flags);
     185        async_obsolete_msg_3(fb_info.phone, FB_SET_COLOR, fgcolor, bgcolor, flags);
    159186}
    160187
    161188static void set_rgb_color(uint32_t fgcolor, uint32_t bgcolor)
    162189{
    163         async_msg_2(fb_info.phone, FB_SET_RGB_COLOR, fgcolor, bgcolor);
     190        async_obsolete_msg_2(fb_info.phone, FB_SET_RGB_COLOR, fgcolor, bgcolor);
    164191}
    165192
     
    216243                }
    217244               
    218                 async_req_4_0(fb_info.phone, FB_DRAW_TEXT_DATA,
     245                async_obsolete_req_4_0(fb_info.phone, FB_DRAW_TEXT_DATA,
    219246                    x0, y0, width, height);
    220247        }
     
    257284static void fb_putchar(wchar_t c, sysarg_t col, sysarg_t row)
    258285{
    259         async_msg_3(fb_info.phone, FB_PUTCHAR, c, col, row);
     286        async_obsolete_msg_3(fb_info.phone, FB_PUTCHAR, c, col, row);
    260287}
    261288
     
    306333               
    307334                if (cons == active_console)
    308                         async_msg_1(fb_info.phone, FB_SCROLL, 1);
     335                        async_obsolete_msg_1(fb_info.phone, FB_SCROLL, 1);
    309336        }
    310337       
     
    323350       
    324351        if (cons == kernel_console) {
    325                 async_serialize_start();
     352                console_serialize_start();
    326353                curs_hide_sync();
    327354                gcons_in_kernel();
    328355                screen_yield();
    329                 kbd_yield();
    330                 async_serialize_end();
    331                
    332                 if (__SYSCALL0(SYS_DEBUG_ENABLE_CONSOLE)) {
     356                input_yield();
     357                console_serialize_end();
     358               
     359                if (console_kcon()) {
    333360                        prev_console = active_console;
    334361                        active_console = kernel_console;
     
    338365       
    339366        if (cons != kernel_console) {
    340                 async_serialize_start();
     367                console_serialize_start();
    341368               
    342369                if (active_console == kernel_console) {
    343370                        screen_reclaim();
    344                         kbd_reclaim();
     371                        input_reclaim();
    345372                        gcons_redraw_console();
    346373                }
     
    365392                       
    366393                        /* This call can preempt, but we are already at the end */
    367                         rc = async_req_4_0(fb_info.phone, FB_DRAW_TEXT_DATA,
     394                        rc = async_obsolete_req_4_0(fb_info.phone, FB_DRAW_TEXT_DATA,
    368395                            0, 0, cons->scr.size_x,
    369396                            cons->scr.size_y);
     
    393420                curs_visibility(cons->scr.is_cursor_visible);
    394421               
    395                 async_serialize_end();
    396         }
    397 }
    398 
    399 /** Handler for keyboard */
    400 static void keyboard_events(ipc_callid_t iid, ipc_call_t *icall)
     422                console_serialize_end();
     423        }
     424}
     425
     426/** Handler for input events */
     427static void input_events(ipc_callid_t iid, ipc_call_t *icall, void *arg)
    401428{
    402429        /* Ignore parameters, the connection is already opened */
     
    406433               
    407434                int retval;
    408                 console_event_t ev;
     435                kbd_event_t ev;
     436               
     437                if (!IPC_GET_IMETHOD(call)) {
     438                        /* TODO: Handle hangup */
     439                        async_hangup(input_sess);
     440                        return;
     441                }
    409442               
    410443                switch (IPC_GET_IMETHOD(call)) {
    411                 case IPC_M_PHONE_HUNGUP:
    412                         /* TODO: Handle hangup */
    413                         return;
    414                 case KBD_EVENT:
    415                         /* Got event from keyboard driver. */
     444                case INPUT_EVENT_KEY:
     445                        /* Got key press/release event */
    416446                        retval = 0;
    417447                        ev.type = IPC_GET_ARG1(call);
     
    434464                        fibril_mutex_unlock(&input_mutex);
    435465                        break;
    436                 default:
    437                         retval = ENOENT;
    438                 }
    439                 async_answer_0(callid, retval);
    440         }
    441 }
    442 
    443 /** Handler for mouse events */
    444 static 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:
     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 */
    458474                        if (IPC_GET_ARG1(call) == 1) {
    459475                                int newcon = gcons_mouse_btn((bool) IPC_GET_ARG2(call));
     
    463479                        retval = 0;
    464480                        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;
    470481                default:
    471482                        retval = ENOENT;
     
    487498        }
    488499       
    489         async_serialize_start();
     500        console_serialize_start();
    490501       
    491502        size_t off = 0;
     
    495506        }
    496507       
    497         async_serialize_end();
     508        console_serialize_end();
    498509       
    499510        gcons_notify_char(cons->index);
     
    521532       
    522533        size_t pos = 0;
    523         console_event_t ev;
     534        kbd_event_t ev;
    524535        fibril_mutex_lock(&input_mutex);
    525536       
     
    546557static void cons_get_event(console_t *cons, ipc_callid_t rid, ipc_call_t *request)
    547558{
    548         console_event_t ev;
     559        kbd_event_t ev;
    549560       
    550561        fibril_mutex_lock(&input_mutex);
     
    562573
    563574/** Default thread for new connections */
    564 static void client_connection(ipc_callid_t iid, ipc_call_t *icall)
     575static void client_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
    565576{
    566577        console_t *cons = NULL;
     
    590601        int rc;
    591602       
    592         async_serialize_start();
     603        console_serialize_start();
    593604        if (cons->refcount == 0)
    594605                gcons_notify_connect(cons->index);
     
    600611       
    601612        while (true) {
    602                 async_serialize_end();
     613                console_serialize_end();
    603614                callid = async_get_call(&call);
    604                 async_serialize_start();
     615                console_serialize_start();
    605616               
    606617                arg1 = 0;
     
    608619                arg3 = 0;
    609620               
    610                 switch (IPC_GET_IMETHOD(call)) {
    611                 case IPC_M_PHONE_HUNGUP:
     621                if (!IPC_GET_IMETHOD(call)) {
    612622                        cons->refcount--;
    613623                        if (cons->refcount == 0)
    614624                                gcons_notify_disconnect(cons->index);
     625                        console_serialize_end();
    615626                        return;
     627                }
     628               
     629                switch (IPC_GET_IMETHOD(call)) {
    616630                case VFS_OUT_READ:
    617                         async_serialize_end();
     631                        console_serialize_end();
    618632                        cons_read(cons, callid, &call);
    619                         async_serialize_start();
     633                        console_serialize_start();
    620634                        continue;
    621635                case VFS_OUT_WRITE:
    622                         async_serialize_end();
     636                        console_serialize_end();
    623637                        cons_write(cons, callid, &call);
    624                         async_serialize_start();
     638                        console_serialize_start();
    625639                        continue;
    626640                case VFS_OUT_SYNC:
    627641                        fb_pending_flush();
    628642                        if (cons == active_console) {
    629                                 async_req_0_0(fb_info.phone, FB_FLUSH);
     643                                async_obsolete_req_0_0(fb_info.phone, FB_FLUSH);
    630644                                curs_goto(cons->scr.position_x, cons->scr.position_y);
    631645                        }
     
    634648                        /* Send message to fb */
    635649                        if (cons == active_console)
    636                                 async_msg_0(fb_info.phone, FB_CLEAR);
     650                                async_obsolete_msg_0(fb_info.phone, FB_CLEAR);
    637651                       
    638652                        screenbuffer_clear(&cons->scr);
     
    693707                        break;
    694708                case CONSOLE_GET_EVENT:
    695                         async_serialize_end();
     709                        console_serialize_end();
    696710                        cons_get_event(cons, callid, &call);
    697                         async_serialize_start();
     711                        console_serialize_start();
    698712                        continue;
    699                 case CONSOLE_KCON_ENABLE:
    700                         change_console(kernel_console);
    701                         break;
    702713                }
    703714                async_answer_3(callid, EOK, arg1, arg2, arg3);
     
    710721}
    711722
    712 static 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);
     723static 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;
     744        }
     745       
     746        /* 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
     761static 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)
    718766                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");
     767       
     768        /* Connect to framebuffer driver */
     769        fb_info.phone = service_obsolete_connect_blocking(SERVICE_VIDEO, 0, 0);
     770        if (fb_info.phone < 0) {
     771                printf("%s: Failed to connect to video service\n", NAME);
    724772                return false;
    725         }
    726        
    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");
    731                 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        
    756 skip_mouse:
    757        
    758         /* Connect to framebuffer driver */
    759         fb_info.phone = service_connect_blocking(SERVICE_VIDEO, 0, 0);
    760         if (fb_info.phone < 0) {
    761                 printf(NAME ": Failed to connect to video service\n");
    762                 return -1;
    763773        }
    764774       
     
    766776        int rc = devmap_driver_register(NAME, client_connection);
    767777        if (rc < 0) {
    768                 printf(NAME ": Unable to register driver (%d)\n", rc);
     778                printf("%s: Unable to register driver (%d)\n", NAME, rc);
    769779                return false;
    770780        }
     
    774784       
    775785        /* Synchronize, the gcons could put something in queue */
    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);
     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);
    779789       
    780790        /* Set up shared memory buffer. */
     
    787797       
    788798        if (interbuffer) {
    789                 if (async_share_out_start(fb_info.phone, interbuffer,
     799                if (async_obsolete_share_out_start(fb_info.phone, interbuffer,
    790800                    AS_AREA_READ) != EOK) {
    791801                        as_area_destroy(interbuffer);
     
    802812                        if (screenbuffer_init(&consoles[i].scr,
    803813                            fb_info.cols, fb_info.rows) == NULL) {
    804                                 printf(NAME ": Unable to allocate screen buffer %zu\n", i);
     814                                printf("%s: Unable to allocate screen buffer %zu\n", NAME, i);
    805815                                return false;
    806816                        }
     
    814824                       
    815825                        if (devmap_device_register(vc, &consoles[i].devmap_handle) != EOK) {
    816                                 printf(NAME ": Unable to register device %s\n", vc);
     826                                printf("%s: Unable to register device %s\n", NAME, vc);
    817827                                return false;
    818828                        }
     
    820830        }
    821831       
    822         /* Disable kernel output to the console */
    823         __SYSCALL0(SYS_DEBUG_DISABLE_CONSOLE);
    824        
    825832        /* Initialize the screen */
    826         async_serialize_start();
     833        console_serialize_start();
    827834        gcons_redraw_console();
    828835        set_style(STYLE_NORMAL);
     
    830837        curs_goto(0, 0);
    831838        curs_visibility(active_console->scr.is_cursor_visible);
    832         async_serialize_end();
     839        console_serialize_end();
    833840       
    834841        /* Receive kernel notifications */
    835842        async_set_interrupt_received(interrupt_received);
    836843        if (event_subscribe(EVENT_KCONSOLE, 0) != EOK)
    837                 printf(NAME ": Error registering kconsole notifications\n");
     844                printf("%s: Error registering kconsole notifications\n", NAME);
    838845       
    839846        return true;
     
    842849static void usage(void)
    843850{
    844         printf("Usage: console <input>\n");
     851        printf("Usage: console <input_dev>\n");
    845852}
    846853
     
    854861        printf(NAME ": HelenOS Console service\n");
    855862       
    856         if (!console_init(argv[1]))
     863        if (!console_srv_init(argv[1]))
    857864                return -1;
    858865       
Note: See TracChangeset for help on using the changeset viewer.