Changeset 593e023 in mainline for uspace/srv/hid/console/console.c


Ignore:
Timestamp:
2014-08-12T17:14:32Z (10 years ago)
Author:
Martin Decky <martin@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
c3bdc92
Parents:
ce3efa0
Message:

allow compositor and console to coexist side-by-side, use the input server as a poor man's seat arbitrator

  • kernel console notifies both about the release and grab events
  • input server arbitrates the seat selection between kernel console and any number of user space UIs (currently the console server and the compositor server)
  • input port yield and reclaim methods have been removed (they are used only on Ski and Niagara, both already need a more generic mechanism for the kernel/user space cooperation)
  • console and compositor server keep track of the kernel console via the input arbitration
  • move the waiting for a character device from init and terminal widget to getterm
File:
1 edited

Legend:

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

    rce3efa0 r593e023  
    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>
     
    8483/** Input server proxy */
    8584static input_t *input;
     85static bool active = false;
    8686
    8787/** Session to the output server */
     
    9898static FIBRIL_MUTEX_INITIALIZE(switch_mtx);
    9999
    100 static console_t *prev_console = &consoles[0];
    101100static console_t *active_console = &consoles[0];
    102 static console_t *kernel_console = &consoles[KERNEL_CONSOLE];
    103 
     101
     102static int input_ev_active(input_t *);
     103static int input_ev_deactive(input_t *);
    104104static int input_ev_key(input_t *, kbd_event_type_t, keycode_t, keymod_t, wchar_t);
    105105static int input_ev_move(input_t *, int, int);
     
    108108
    109109static input_ev_ops_t input_ev_ops = {
     110        .active = input_ev_active,
     111        .deactive = input_ev_deactive,
    110112        .key = input_ev_key,
    111113        .move = input_ev_move,
     
    159161        fibril_mutex_lock(&cons->mtx);
    160162       
    161         if ((cons == active_console) && (active_console != kernel_console)) {
     163        if ((active) && (cons == active_console)) {
    162164                output_update(output_sess, cons->fbid);
    163165                output_cursor_update(output_sess, cons->fbid);
     
    173175        fibril_mutex_lock(&cons->mtx);
    174176       
    175         if ((cons == active_console) && (active_console != kernel_console))
     177        if ((active) && (cons == active_console))
    176178                output_cursor_update(output_sess, cons->fbid);
    177179       
     
    185187        fibril_mutex_lock(&cons->mtx);
    186188       
    187         if ((cons == active_console) && (active_console != kernel_console)) {
     189        if ((active) && (cons == active_console)) {
    188190                output_damage(output_sess, cons->fbid, 0, 0, cons->cols,
    189191                    cons->rows);
     
    195197}
    196198
    197 static void cons_switch(console_t *cons)
    198 {
     199static void cons_switch(unsigned int index)
     200{
     201        /*
     202         * The first undefined index is reserved
     203         * for switching to the kernel console.
     204         */
     205        if (index == CONSOLE_COUNT) {
     206                if (console_kcon())
     207                        active = false;
     208               
     209                return;
     210        }
     211       
     212        if (index > CONSOLE_COUNT)
     213                return;
     214       
     215        console_t *cons = &consoles[index];
     216       
    199217        fibril_mutex_lock(&switch_mtx);
    200218       
     
    204222        }
    205223       
    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;
    219224        active_console = cons;
    220225       
     
    224229}
    225230
    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;
     231static int input_ev_active(input_t *input)
     232{
     233        active = true;
     234        output_claim(output_sess);
     235        cons_damage(active_console);
     236       
     237        return EOK;
     238}
     239
     240static int input_ev_deactive(input_t *input)
     241{
     242        active = false;
     243        output_yield(output_sess);
     244       
     245        return EOK;
    239246}
    240247
     
    242249    keymod_t mods, wchar_t c)
    243250{
    244         if ((key >= KC_F1) && (key < KC_F1 + CONSOLE_COUNT) &&
     251        if ((key >= KC_F1) && (key <= KC_F1 + CONSOLE_COUNT) &&
    245252            ((mods & KM_CTRL) == 0)) {
    246                 cons_switch(&consoles[key - KC_F1]);
     253                cons_switch(key - KC_F1);
    247254        } else {
    248255                /* Got key press/release event */
     
    259266                event->c = c;
    260267               
    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,
     268                prodcons_produce(&active_console->input_pc,
    270269                    &event->link);
    271270        }
     
    509508       
    510509        for (size_t i = 0; i < CONSOLE_COUNT; i++) {
    511                 if (i == KERNEL_CONSOLE)
    512                         continue;
    513                
    514510                if (consoles[i].dsid == (service_id_t) IPC_GET_ARG1(*icall)) {
    515511                        cons = &consoles[i];
     
    556552       
    557553        return EOK;
    558 }
    559 
    560 static void interrupt_received(ipc_callid_t callid, ipc_call_t *call)
    561 {
    562         cons_switch(prev_console);
    563554}
    564555
     
    609600        output_get_caps(output_sess, &ccaps);
    610601       
    611         /* Inititalize consoles */
    612         for (size_t i = 0; i < CONSOLE_COUNT; i++) {
    613                 consoles[i].index = i;
    614                 atomic_set(&consoles[i].refcnt, 0);
    615                 fibril_mutex_initialize(&consoles[i].mtx);
    616                 prodcons_initialize(&consoles[i].input_pc);
    617                 consoles[i].char_remains_len = 0;
    618                
    619                 if (i == KERNEL_CONSOLE)
    620                         continue;
    621                
    622                 consoles[i].cols = cols;
    623                 consoles[i].rows = rows;
    624                 consoles[i].ccaps = ccaps;
    625                 consoles[i].frontbuf =
    626                     chargrid_create(cols, rows, CHARGRID_FLAG_SHARED);
    627                
    628                 if (consoles[i].frontbuf == NULL) {
    629                         printf("%s: Unable to allocate frontbuffer %zu\n", NAME, i);
    630                         return false;
     602        /*
     603         * Inititalize consoles only if there are
     604         * actually some output devices.
     605         */
     606        if (ccaps != 0) {
     607                for (size_t i = 0; i < CONSOLE_COUNT; i++) {
     608                        consoles[i].index = i;
     609                        atomic_set(&consoles[i].refcnt, 0);
     610                        fibril_mutex_initialize(&consoles[i].mtx);
     611                        prodcons_initialize(&consoles[i].input_pc);
     612                        consoles[i].char_remains_len = 0;
     613                       
     614                        consoles[i].cols = cols;
     615                        consoles[i].rows = rows;
     616                        consoles[i].ccaps = ccaps;
     617                        consoles[i].frontbuf =
     618                            chargrid_create(cols, rows, CHARGRID_FLAG_SHARED);
     619                       
     620                        if (consoles[i].frontbuf == NULL) {
     621                                printf("%s: Unable to allocate frontbuffer %zu\n", NAME, i);
     622                                return false;
     623                        }
     624                       
     625                        consoles[i].fbid = output_frontbuf_create(output_sess,
     626                            consoles[i].frontbuf);
     627                        if (consoles[i].fbid == 0) {
     628                                printf("%s: Unable to create frontbuffer %zu\n", NAME, i);
     629                                return false;
     630                        }
     631                       
     632                        con_srvs_init(&consoles[i].srvs);
     633                        consoles[i].srvs.ops = &con_ops;
     634                        consoles[i].srvs.sarg = &consoles[i];
     635                       
     636                        char vc[LOC_NAME_MAXLEN + 1];
     637                        snprintf(vc, LOC_NAME_MAXLEN, "%s/vc%zu", NAMESPACE, i);
     638                       
     639                        if (loc_service_register(vc, &consoles[i].dsid) != EOK) {
     640                                printf("%s: Unable to register device %s\n", NAME, vc);
     641                                return false;
     642                        }
    631643                }
    632644               
    633                 consoles[i].fbid = output_frontbuf_create(output_sess,
    634                     consoles[i].frontbuf);
    635                 if (consoles[i].fbid == 0) {
    636                         printf("%s: Unable to create frontbuffer %zu\n", NAME, i);
    637                         return false;
    638                 }
    639                
    640                 con_srvs_init(&consoles[i].srvs);
    641                 consoles[i].srvs.ops = &con_ops;
    642                 consoles[i].srvs.sarg = &consoles[i];
    643                
    644                 char vc[LOC_NAME_MAXLEN + 1];
    645                 snprintf(vc, LOC_NAME_MAXLEN, "%s/vc%zu", NAMESPACE, i);
    646                
    647                 if (loc_service_register(vc, &consoles[i].dsid) != EOK) {
    648                         printf("%s: Unable to register device %s\n", NAME, vc);
    649                         return false;
    650                 }
    651         }
    652        
    653         cons_damage(active_console);
    654        
    655         /* Receive kernel notifications */
    656         async_set_interrupt_received(interrupt_received);
    657         rc = event_subscribe(EVENT_KCONSOLE, 0);
    658         if (rc != EOK)
    659                 printf("%s: Failed to register kconsole notifications (%s)\n",
    660                     NAME, str_error(rc));
     645                input_activate(input);
     646        }
    661647       
    662648        return true;
Note: See TracChangeset for help on using the changeset viewer.