Changeset 77ffa01 in mainline for uspace/lib/ui/src/ui.c


Ignore:
Timestamp:
2021-02-27T21:34:15Z (3 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
9c7dc8e
Parents:
b433f68
Message:

Allow UI to run in the console

Note that everything is way too large.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/ui/src/ui.c

    rb433f68 r77ffa01  
    11/*
    2  * Copyright (c) 2020 Jiri Svoboda
     2 * Copyright (c) 2021 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    3434 */
    3535
     36#include <ctype.h>
    3637#include <display.h>
    3738#include <errno.h>
    3839#include <fibril.h>
     40#include <io/console.h>
    3941#include <stdlib.h>
     42#include <str.h>
    4043#include <task.h>
    4144#include <ui/ui.h>
     45#include <ui/wdecor.h>
     46#include "../private/window.h"
    4247#include "../private/ui.h"
     48
     49/** Parse output specification.
     50 *
     51 * Output specification has the form <proto>@<service> where proto is
     52 * eiher 'disp' for display service or 'cons' for console. Service
     53 * is a location ID service name (e.g. hid/display).
     54 *
     55 * @param ospec Output specification
     56 * @param ws Place to store window system type (protocol)
     57 * @param osvc Place to store pointer to output service name
     58 */
     59static void ui_ospec_parse(const char *ospec, ui_winsys_t *ws,
     60    const char **osvc)
     61{
     62        const char *cp;
     63
     64        if (ospec == UI_DISPLAY_DEFAULT) {
     65                *ws = ui_ws_display;
     66                *osvc = DISPLAY_DEFAULT;
     67                return;
     68        }
     69
     70        cp = ospec;
     71        while (isalpha(*cp))
     72                ++cp;
     73
     74        if (*cp == '@') {
     75                if (str_lcmp(ospec, "disp@", str_length("disp@")) == 0) {
     76                        *ws = ui_ws_display;
     77                } else if (str_lcmp(ospec, "cons@", str_length("cons@")) == 0) {
     78                        *ws = ui_ws_console;
     79                } else {
     80                        *ws = ui_ws_unknown;
     81                }
     82
     83                if (cp[1] != '\0')
     84                        *osvc = cp + 1;
     85                else
     86                        *osvc = NULL;
     87        } else {
     88                *ws = ui_ws_display;
     89                *osvc = ospec;
     90        }
     91}
    4392
    4493/** Create new user interface.
     
    53102        errno_t rc;
    54103        display_t *display;
     104        console_ctrl_t *console;
     105        ui_winsys_t ws;
     106        const char *osvc;
    55107        ui_t *ui;
    56108
    57         rc = display_open(ospec, &display);
    58         if (rc != EOK)
    59                 return rc;
    60 
    61         rc = ui_create_disp(display, &ui);
    62         if (rc != EOK) {
    63                 display_close(display);
    64                 return rc;
    65         }
    66 
    67         ui->display = display;
     109        ui_ospec_parse(ospec, &ws, &osvc);
     110
     111        if (ws == ui_ws_display) {
     112                rc = display_open(osvc, &display);
     113                if (rc != EOK)
     114                        return rc;
     115
     116                rc = ui_create_disp(display, &ui);
     117                if (rc != EOK) {
     118                        display_close(display);
     119                        return rc;
     120                }
     121        } else if (ws == ui_ws_console) {
     122                console = console_init(stdin, stdout);
     123                if (console == NULL)
     124                        return EIO;
     125
     126                /* ws == ui_ws_console */
     127                rc = ui_create_cons(console, &ui);
     128                if (rc != EOK) {
     129                        console_done(console);
     130                        return rc;
     131                }
     132        } else {
     133                return EINVAL;
     134        }
     135
    68136        ui->myoutput = true;
    69137        *rui = ui;
     
    71139}
    72140
     141/** Create new user interface using console service.
     142 *
     143 * @param rui Place to store pointer to new UI
     144 * @return EOK on success or an error code
     145 */
     146errno_t ui_create_cons(console_ctrl_t *console, ui_t **rui)
     147{
     148        ui_t *ui;
     149
     150        ui = calloc(1, sizeof(ui_t));
     151        if (ui == NULL)
     152                return ENOMEM;
     153
     154        ui->console = console;
     155        *rui = ui;
     156        return EOK;
     157}
     158
    73159/** Create new user interface using display service.
    74160 *
     
    99185                return;
    100186
    101         if (ui->myoutput)
    102                 display_close(ui->display);
     187        if (ui->myoutput) {
     188                if (ui->console != NULL)
     189                        console_done(ui->console);
     190                if (ui->display != NULL)
     191                        display_close(ui->display);
     192        }
     193
    103194        free(ui);
     195}
     196
     197static void ui_cons_event_process(ui_t *ui, cons_event_t *event)
     198{
     199        if (ui->root_wnd == NULL)
     200                return;
     201
     202        switch (event->type) {
     203        case CEV_KEY:
     204                ui_window_send_kbd(ui->root_wnd, &event->ev.key);
     205                break;
     206        case CEV_POS:
     207                ui_wdecor_pos_event(ui->root_wnd->wdecor, &event->ev.pos);
     208                ui_window_send_pos(ui->root_wnd, &event->ev.pos);
     209                break;
     210        }
    104211}
    105212
     
    113220void ui_run(ui_t *ui)
    114221{
    115         task_retval(0);
    116 
    117         while (!ui->quit)
    118                 fibril_usleep(100000);
     222        bool have_event;
     223        cons_event_t event;
     224        usec_t timeout;
     225
     226        /* Only return command prompt if we are running in a separate window */
     227        if (ui->display != NULL)
     228                task_retval(0);
     229
     230        while (!ui->quit) {
     231                if (ui->console != NULL) {
     232                        timeout = 100000;
     233                        have_event = console_get_event_timeout(ui->console,
     234                            &event, &timeout);
     235                        if (have_event)
     236                                ui_cons_event_process(ui, &event);
     237                } else {
     238                        fibril_usleep(100000);
     239                }
     240        }
    119241}
    120242
Note: See TracChangeset for help on using the changeset viewer.