Ignore:
File:
1 edited

Legend:

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

    r902f0906 r2f6ad06  
    4141#include <str_error.h>
    4242#include <loc.h>
    43 #include <event.h>
    4443#include <io/con_srv.h>
    4544#include <io/kbd_event.h>
     
    5049#include <malloc.h>
    5150#include <as.h>
     51#include <task.h>
    5252#include <fibril_synch.h>
    5353#include "console.h"
     
    8484/** Input server proxy */
    8585static input_t *input;
     86static bool active = false;
    8687
    8788/** Session to the output server */
     
    9899static FIBRIL_MUTEX_INITIALIZE(switch_mtx);
    99100
    100 static console_t *prev_console = &consoles[0];
    101101static console_t *active_console = &consoles[0];
    102 static console_t *kernel_console = &consoles[KERNEL_CONSOLE];
    103 
     102
     103static int input_ev_active(input_t *);
     104static int input_ev_deactive(input_t *);
    104105static int input_ev_key(input_t *, kbd_event_type_t, keycode_t, keymod_t, wchar_t);
    105106static int input_ev_move(input_t *, int, int);
     
    108109
    109110static input_ev_ops_t input_ev_ops = {
     111        .active = input_ev_active,
     112        .deactive = input_ev_deactive,
    110113        .key = input_ev_key,
    111114        .move = input_ev_move,
     
    159162        fibril_mutex_lock(&cons->mtx);
    160163       
    161         if ((cons == active_console) && (active_console != kernel_console)) {
     164        if ((active) && (cons == active_console)) {
    162165                output_update(output_sess, cons->fbid);
    163166                output_cursor_update(output_sess, cons->fbid);
     
    173176        fibril_mutex_lock(&cons->mtx);
    174177       
    175         if ((cons == active_console) && (active_console != kernel_console))
     178        if ((active) && (cons == active_console))
    176179                output_cursor_update(output_sess, cons->fbid);
    177180       
     
    185188        fibril_mutex_lock(&cons->mtx);
    186189       
    187         if ((cons == active_console) && (active_console != kernel_console)) {
     190        if ((active) && (cons == active_console)) {
    188191                output_damage(output_sess, cons->fbid, 0, 0, cons->cols,
    189192                    cons->rows);
     
    195198}
    196199
    197 static void cons_switch(console_t *cons)
    198 {
     200static void cons_switch(unsigned int index)
     201{
     202        /*
     203         * The first undefined index is reserved
     204         * for switching to the kernel console.
     205         */
     206        if (index == CONSOLE_COUNT) {
     207                if (console_kcon())
     208                        active = false;
     209               
     210                return;
     211        }
     212       
     213        if (index > CONSOLE_COUNT)
     214                return;
     215       
     216        console_t *cons = &consoles[index];
     217       
    199218        fibril_mutex_lock(&switch_mtx);
    200219       
     
    204223        }
    205224       
    206         if (cons == kernel_console) {
    207                 output_yield(output_sess);
    208                 if (!console_kcon()) {
    209                         output_claim(output_sess);
    210                         fibril_mutex_unlock(&switch_mtx);
    211                         return;
    212                 }
    213         }
    214        
    215         if (active_console == kernel_console)
    216                 output_claim(output_sess);
    217        
    218         prev_console = active_console;
    219225        active_console = cons;
    220226       
     
    224230}
    225231
    226 static console_t *cons_get_active_uspace(void)
    227 {
    228         fibril_mutex_lock(&switch_mtx);
    229        
    230         console_t *active_uspace = active_console;
    231         if (active_uspace == kernel_console)
    232                 active_uspace = prev_console;
    233        
    234         assert(active_uspace != kernel_console);
    235        
    236         fibril_mutex_unlock(&switch_mtx);
    237        
    238         return active_uspace;
     232static int input_ev_active(input_t *input)
     233{
     234        active = true;
     235        output_claim(output_sess);
     236        cons_damage(active_console);
     237       
     238        return EOK;
     239}
     240
     241static int input_ev_deactive(input_t *input)
     242{
     243        active = false;
     244        output_yield(output_sess);
     245       
     246        return EOK;
    239247}
    240248
     
    242250    keymod_t mods, wchar_t c)
    243251{
    244         if ((key >= KC_F1) && (key < KC_F1 + CONSOLE_COUNT) &&
     252        if ((key >= KC_F1) && (key <= KC_F1 + CONSOLE_COUNT) &&
    245253            ((mods & KM_CTRL) == 0)) {
    246                 cons_switch(&consoles[key - KC_F1]);
     254                cons_switch(key - KC_F1);
    247255        } else {
    248256                /* Got key press/release event */
     
    259267                event->c = c;
    260268               
    261                 /*
    262                  * Kernel console does not read events
    263                  * from us, so we will redirect them
    264                  * to the (last) active userspace console
    265                  * if necessary.
    266                  */
    267                 console_t *target_console = cons_get_active_uspace();
    268                
    269                 prodcons_produce(&target_console->input_pc,
     269                prodcons_produce(&active_console->input_pc,
    270270                    &event->link);
    271271        }
     
    377377                }
    378378        }
    379 
     379       
    380380        return size;
    381381}
     
    388388        while (off < size)
    389389                cons_write_char(cons, str_decode(data, &off, size));
     390       
    390391        return size;
    391392}
     
    498499        event->type = CEV_KEY;
    499500        event->ev.key = *kevent;
     501       
    500502        free(kevent);
    501503        return EOK;
     
    507509       
    508510        for (size_t i = 0; i < CONSOLE_COUNT; i++) {
    509                 if (i == KERNEL_CONSOLE)
    510                         continue;
    511                
    512                 if (consoles[i].dsid == (service_id_t) IPC_GET_ARG1(*icall)) {
     511                if (consoles[i].dsid == (service_id_t) IPC_GET_ARG2(*icall)) {
    513512                        cons = &consoles[i];
    514513                        break;
     
    526525        con_conn(iid, icall, &cons->srvs);
    527526}
    528 
    529527
    530528static int input_connect(const char *svc)
     
    539537        }
    540538
    541         sess = loc_service_connect(EXCHANGE_ATOMIC, dsid, 0);
     539        sess = loc_service_connect(dsid, INTERFACE_INPUT, 0);
    542540        if (sess == NULL) {
    543541                printf("%s: Unable to connect to input service %s\n", NAME,
     
    557555}
    558556
    559 static void interrupt_received(ipc_callid_t callid, ipc_call_t *call)
    560 {
    561         cons_switch(prev_console);
    562 }
    563 
    564557static async_sess_t *output_connect(const char *svc)
    565558{
     
    569562        int rc = loc_service_get_id(svc, &dsid, 0);
    570563        if (rc == EOK) {
    571                 sess = loc_service_connect(EXCHANGE_SERIALIZE, dsid, 0);
     564                sess = loc_service_connect(dsid, INTERFACE_OUTPUT, 0);
    572565                if (sess == NULL) {
    573566                        printf("%s: Unable to connect to output service %s\n",
     
    583576static bool console_srv_init(char *input_svc, char *output_svc)
    584577{
    585         int rc;
    586        
    587578        /* Connect to input service */
    588         rc = input_connect(input_svc);
     579        int rc = input_connect(input_svc);
    589580        if (rc != EOK)
    590581                return false;
     
    596587       
    597588        /* Register server */
    598         async_set_client_connection(client_connection);
     589        async_set_fallback_port_handler(client_connection, NULL);
    599590        rc = loc_server_register(NAME);
    600591        if (rc != EOK) {
     
    610601        output_get_caps(output_sess, &ccaps);
    611602       
    612         /* Inititalize consoles */
    613         for (size_t i = 0; i < CONSOLE_COUNT; i++) {
    614                 consoles[i].index = i;
    615                 atomic_set(&consoles[i].refcnt, 0);
    616                 fibril_mutex_initialize(&consoles[i].mtx);
    617                 prodcons_initialize(&consoles[i].input_pc);
    618                 consoles[i].char_remains_len = 0;
    619                
    620                 if (i == KERNEL_CONSOLE)
    621                         continue;
    622                
    623                 consoles[i].cols = cols;
    624                 consoles[i].rows = rows;
    625                 consoles[i].ccaps = ccaps;
    626                 consoles[i].frontbuf =
    627                     chargrid_create(cols, rows, CHARGRID_FLAG_SHARED);
    628                
    629                 if (consoles[i].frontbuf == NULL) {
    630                         printf("%s: Unable to allocate frontbuffer %zu\n", NAME, i);
    631                         return false;
     603        /*
     604         * Inititalize consoles only if there are
     605         * actually some output devices.
     606         */
     607        if (ccaps != 0) {
     608                for (size_t i = 0; i < CONSOLE_COUNT; i++) {
     609                        consoles[i].index = i;
     610                        atomic_set(&consoles[i].refcnt, 0);
     611                        fibril_mutex_initialize(&consoles[i].mtx);
     612                        prodcons_initialize(&consoles[i].input_pc);
     613                        consoles[i].char_remains_len = 0;
     614                       
     615                        consoles[i].cols = cols;
     616                        consoles[i].rows = rows;
     617                        consoles[i].ccaps = ccaps;
     618                        consoles[i].frontbuf =
     619                            chargrid_create(cols, rows, CHARGRID_FLAG_SHARED);
     620                       
     621                        if (consoles[i].frontbuf == NULL) {
     622                                printf("%s: Unable to allocate frontbuffer %zu\n", NAME, i);
     623                                return false;
     624                        }
     625                       
     626                        consoles[i].fbid = output_frontbuf_create(output_sess,
     627                            consoles[i].frontbuf);
     628                        if (consoles[i].fbid == 0) {
     629                                printf("%s: Unable to create frontbuffer %zu\n", NAME, i);
     630                                return false;
     631                        }
     632                       
     633                        con_srvs_init(&consoles[i].srvs);
     634                        consoles[i].srvs.ops = &con_ops;
     635                        consoles[i].srvs.sarg = &consoles[i];
     636                       
     637                        char vc[LOC_NAME_MAXLEN + 1];
     638                        snprintf(vc, LOC_NAME_MAXLEN, "%s/vc%zu", NAMESPACE, i);
     639                       
     640                        if (loc_service_register(vc, &consoles[i].dsid) != EOK) {
     641                                printf("%s: Unable to register device %s\n", NAME, vc);
     642                                return false;
     643                        }
    632644                }
    633645               
    634                 consoles[i].fbid = output_frontbuf_create(output_sess,
    635                     consoles[i].frontbuf);
    636                 if (consoles[i].fbid == 0) {
    637                         printf("%s: Unable to create frontbuffer %zu\n", NAME, i);
    638                         return false;
    639                 }
    640                
    641                 con_srvs_init(&consoles[i].srvs);
    642                 consoles[i].srvs.ops = &con_ops;
    643                 consoles[i].srvs.sarg = &consoles[i];
    644                
    645                 char vc[LOC_NAME_MAXLEN + 1];
    646                 snprintf(vc, LOC_NAME_MAXLEN, "%s/vc%zu", NAMESPACE, i);
    647                
    648                 if (loc_service_register(vc, &consoles[i].dsid) != EOK) {
    649                         printf("%s: Unable to register device %s\n", NAME, vc);
    650                         return false;
    651                 }
    652         }
    653        
    654         cons_damage(active_console);
    655        
    656         /* Receive kernel notifications */
    657         async_set_interrupt_received(interrupt_received);
    658         rc = event_subscribe(EVENT_KCONSOLE, 0);
    659         if (rc != EOK)
    660                 printf("%s: Failed to register kconsole notifications (%s)\n",
    661                     NAME, str_error(rc));
     646                input_activate(input);
     647        }
    662648       
    663649        return true;
Note: See TracChangeset for help on using the changeset viewer.