Subversion Repositories HelenOS

Rev

Rev 4538 | Rev 4571 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 4538 Rev 4542
Line 49... Line 49...
49
#include <stdio.h>
49
#include <stdio.h>
50
#include <string.h>
50
#include <string.h>
51
#include <sysinfo.h>
51
#include <sysinfo.h>
52
#include <event.h>
52
#include <event.h>
53
#include <devmap.h>
53
#include <devmap.h>
-
 
54
#include <assert.h>
-
 
55
#include <fibril_sync.h>
54
 
56
 
55
#include "console.h"
57
#include "console.h"
56
#include "gcons.h"
58
#include "gcons.h"
57
#include "screenbuffer.h"
59
#include "screenbuffer.h"
58
 
60
 
Line 109... Line 111...
109
    char *data;           /**< Already stored data */
111
    char *data;           /**< Already stored data */
110
} pending_input_t;
112
} pending_input_t;
111
 
113
 
112
LIST_INITIALIZE(pending_input);
114
LIST_INITIALIZE(pending_input);
113
 
115
 
-
 
116
static FIBRIL_MUTEX_INITIALIZE(input_mutex);
-
 
117
static FIBRIL_CONDVAR_INITIALIZE(input_cv);
-
 
118
static input_flag = false;
-
 
119
 
114
/** Process pending input requests */
120
/** Process pending input requests */
115
static void process_pending_input(void)
121
static void process_pending_input(void)
116
{
122
{
117
    async_serialize_start();
-
 
118
   
-
 
119
    link_t *cur;
123
    link_t *cur;
120
   
124
   
121
loop:
125
loop:
-
 
126
    fibril_mutex_lock(&input_mutex);
-
 
127
    while (!input_flag)
-
 
128
        fibril_condvar_wait(&input_cv, &input_mutex);
-
 
129
rescan:
122
    for (cur = pending_input.next; cur != &pending_input; cur = cur->next) {
130
    for (cur = pending_input.next; cur != &pending_input; cur = cur->next) {
123
        pending_input_t *pr = list_get_instance(cur, pending_input_t, link);
131
        pending_input_t *pr = list_get_instance(cur, pending_input_t, link);
124
       
132
       
125
        console_event_t ev;
133
        console_event_t ev;
126
        if (keybuffer_pop(&pr->cons->keybuffer, &ev)) {
134
        if (keybuffer_pop(&pr->cons->keybuffer, &ev)) {
Line 130... Line 138...
130
                    pr->data[pr->pos] = ev.c;
138
                    pr->data[pr->pos] = ev.c;
131
                    pr->pos++;
139
                    pr->pos++;
132
                }
140
                }
133
            } else {
141
            } else {
134
                ipc_answer_4(pr->rid, EOK, ev.type, ev.key, ev.mods, ev.c);
142
                ipc_answer_4(pr->rid, EOK, ev.type, ev.key, ev.mods, ev.c);
135
               
-
 
136
                list_remove(cur);
143
                list_remove(cur);
137
                free(pr);
144
                free(pr);
138
               
-
 
139
                goto loop;
145
                goto rescan;
140
            }
146
            }
141
        }
147
        }
142
       
148
       
143
        if ((pr->data != NULL) && (pr->pos == pr->size)) {
149
        if ((pr->data != NULL) && (pr->pos == pr->size)) {
144
            (void) ipc_data_read_finalize(pr->callid, pr->data, pr->size);
150
            (void) ipc_data_read_finalize(pr->callid, pr->data, pr->size);
145
            ipc_answer_1(pr->rid, EOK, pr->size);
151
            ipc_answer_1(pr->rid, EOK, pr->size);
146
           
152
 
147
            free(pr->data);
153
            free(pr->data);
148
            list_remove(cur);
154
            list_remove(cur);
149
            free(pr);
155
            free(pr);
150
           
-
 
151
            goto loop;
156
            goto rescan;
152
        }
157
        }
153
    }
158
    }
154
   
159
    input_flag = false;
155
    async_serialize_end();
160
    fibril_mutex_unlock(&input_mutex);
-
 
161
    goto loop;
156
}
162
}
157
 
163
 
158
static void curs_visibility(bool visible)
164
static void curs_visibility(bool visible)
159
{
165
{
160
    async_msg_1(fb_info.phone, FB_CURSOR_VISIBILITY, visible);
166
    async_msg_1(fb_info.phone, FB_CURSOR_VISIBILITY, visible);
Line 451... Line 457...
451
                else
457
                else
452
                    change_console(&consoles[ev.key - KC_F1]);
458
                    change_console(&consoles[ev.key - KC_F1]);
453
                break;
459
                break;
454
            }
460
            }
455
           
461
           
-
 
462
            fibril_mutex_lock(&input_mutex);
456
            keybuffer_push(&active_console->keybuffer, &ev);
463
            keybuffer_push(&active_console->keybuffer, &ev);
-
 
464
            input_flag = true;
-
 
465
            fibril_condvar_signal(&input_cv);
-
 
466
            fibril_mutex_unlock(&input_mutex);
457
            break;
467
            break;
458
        default:
468
        default:
459
            retval = ENOENT;
469
            retval = ENOENT;
460
        }
470
        }
461
        ipc_answer_0(callid, retval);
471
        ipc_answer_0(callid, retval);
Line 512... Line 522...
512
        ipc_answer_0(callid, ENOMEM);
522
        ipc_answer_0(callid, ENOMEM);
513
        ipc_answer_0(rid, ENOMEM);
523
        ipc_answer_0(rid, ENOMEM);
514
        return;
524
        return;
515
    }
525
    }
516
   
526
   
517
    async_serialize_start();
-
 
518
   
-
 
519
    size_t pos = 0;
527
    size_t pos = 0;
520
    console_event_t ev;
528
    console_event_t ev;
-
 
529
    fibril_mutex_lock(&input_mutex);
521
    while ((keybuffer_pop(&cons->keybuffer, &ev)) && (pos < size)) {
530
    while ((keybuffer_pop(&cons->keybuffer, &ev)) && (pos < size)) {
522
        if (ev.type == KEY_PRESS) {
531
        if (ev.type == KEY_PRESS) {
523
            buf[pos] = ev.c;
532
            buf[pos] = ev.c;
524
            pos++;
533
            pos++;
525
        }
534
        }
Line 530... Line 539...
530
        ipc_answer_1(rid, EOK, size);
539
        ipc_answer_1(rid, EOK, size);
531
        free(buf);
540
        free(buf);
532
    } else {
541
    } else {
533
        pending_input_t *pr = (pending_input_t *) malloc(sizeof(pending_input_t));
542
        pending_input_t *pr = (pending_input_t *) malloc(sizeof(pending_input_t));
534
        if (!pr) {
543
        if (!pr) {
-
 
544
            fibril_mutex_unlock(&input_mutex);
535
            ipc_answer_0(callid, ENOMEM);
545
            ipc_answer_0(callid, ENOMEM);
536
            ipc_answer_0(rid, ENOMEM);
546
            ipc_answer_0(rid, ENOMEM);
537
            free(buf);
547
            free(buf);
538
            async_serialize_end();
-
 
539
            return;
548
            return;
540
        }
549
        }
541
       
550
       
542
        pr->cons = cons;
551
        pr->cons = cons;
543
        pr->rid = rid;
552
        pr->rid = rid;
Line 545... Line 554...
545
        pr->pos = pos;
554
        pr->pos = pos;
546
        pr->size = size;
555
        pr->size = size;
547
        pr->data = buf;
556
        pr->data = buf;
548
        list_append(&pr->link, &pending_input);
557
        list_append(&pr->link, &pending_input);
549
    }
558
    }
550
   
-
 
551
    async_serialize_end();
559
    fibril_mutex_unlock(&input_mutex);
552
}
560
}
553
 
561
 
554
static void cons_get_event(console_t *cons, ipc_callid_t rid, ipc_call_t *request)
562
static void cons_get_event(console_t *cons, ipc_callid_t rid, ipc_call_t *request)
555
{
563
{
556
    async_serialize_start();
-
 
557
   
-
 
558
    console_event_t ev;
564
    console_event_t ev;
-
 
565
 
-
 
566
    fibril_mutex_lock(&input_mutex);
559
    if (keybuffer_pop(&cons->keybuffer, &ev)) {
567
    if (keybuffer_pop(&cons->keybuffer, &ev)) {
560
        ipc_answer_4(rid, EOK, ev.type, ev.key, ev.mods, ev.c);
568
        ipc_answer_4(rid, EOK, ev.type, ev.key, ev.mods, ev.c);
561
    } else {
569
    } else {
562
        pending_input_t *pr = (pending_input_t *) malloc(sizeof(pending_input_t));
570
        pending_input_t *pr = (pending_input_t *) malloc(sizeof(pending_input_t));
563
        if (!pr) {
571
        if (!pr) {
-
 
572
            fibril_mutex_unlock(&input_mutex);
564
            ipc_answer_0(rid, ENOMEM);
573
            ipc_answer_0(rid, ENOMEM);
565
            async_serialize_end();
-
 
566
            return;
574
            return;
567
        }
575
        }
568
       
576
       
569
        pr->cons = cons;
577
        pr->cons = cons;
570
        pr->rid = rid;
578
        pr->rid = rid;
571
        pr->callid = 0;
579
        pr->callid = 0;
572
        pr->data = NULL;
580
        pr->data = NULL;
573
        list_append(&pr->link, &pending_input);
581
        list_append(&pr->link, &pending_input);
574
    }
582
    }
575
   
-
 
576
    async_serialize_end();
583
    fibril_mutex_unlock(&input_mutex);
577
}
584
}
578
 
585
 
579
/** Default thread for new connections */
586
/** Default thread for new connections */
580
static void client_connection(ipc_callid_t iid, ipc_call_t *icall)
587
static void client_connection(ipc_callid_t iid, ipc_call_t *icall)
581
{
588
{
Line 713... Line 720...
713
    change_console(prev_console);
720
    change_console(prev_console);
714
}
721
}
715
 
722
 
716
static bool console_init(void)
723
static bool console_init(void)
717
{
724
{
718
    async_serialize_start();
-
 
719
   
-
 
720
    /* Connect to keyboard driver */
725
    /* Connect to keyboard driver */
721
    kbd_phone = ipc_connect_me_to_blocking(PHONE_NS, SERVICE_KEYBOARD, 0, 0);
726
    kbd_phone = ipc_connect_me_to_blocking(PHONE_NS, SERVICE_KEYBOARD, 0, 0);
722
    if (kbd_phone < 0) {
727
    if (kbd_phone < 0) {
723
        printf(NAME ": Failed to connect to keyboard service\n");
728
        printf(NAME ": Failed to connect to keyboard service\n");
724
        async_serialize_end();
-
 
725
        return false;
729
        return false;
726
    }
730
    }
727
   
731
   
728
    ipcarg_t phonehash;
732
    ipcarg_t phonehash;
729
    if (ipc_connect_to_me(kbd_phone, SERVICE_CONSOLE, 0, 0, &phonehash) != 0) {
733
    if (ipc_connect_to_me(kbd_phone, SERVICE_CONSOLE, 0, 0, &phonehash) != 0) {
730
        printf(NAME ": Failed to create callback from keyboard service\n");
734
        printf(NAME ": Failed to create callback from keyboard service\n");
731
        async_serialize_end();
-
 
732
        return false;
735
        return false;
733
    }
736
    }
734
   
737
   
735
    async_set_pending(process_pending_input);
-
 
736
    async_new_connection(phonehash, 0, NULL, keyboard_events);
738
    async_new_connection(phonehash, 0, NULL, keyboard_events);
-
 
739
 
-
 
740
    fid_t fid = fibril_create(process_pending_input, NULL);
-
 
741
    if (!fid) {
-
 
742
        printf(NAME ": Failed to create fibril for handling pending "
-
 
743
            "input\n");
-
 
744
        return -1;
-
 
745
    }
-
 
746
    fibril_add_ready(fid);
737
   
747
   
738
    /* Connect to framebuffer driver */
748
    /* Connect to framebuffer driver */
739
    fb_info.phone = ipc_connect_me_to_blocking(PHONE_NS, SERVICE_VIDEO, 0, 0);
749
    fb_info.phone = ipc_connect_me_to_blocking(PHONE_NS, SERVICE_VIDEO, 0, 0);
740
    if (fb_info.phone < 0) {
750
    if (fb_info.phone < 0) {
741
        printf(NAME ": Failed to connect to video service\n");
751
        printf(NAME ": Failed to connect to video service\n");
742
        async_serialize_end();
-
 
743
        return -1;
752
        return -1;
744
    }
753
    }
745
   
754
   
746
    /* Register driver */
755
    /* Register driver */
747
    int rc = devmap_driver_register(NAME, client_connection);
756
    int rc = devmap_driver_register(NAME, client_connection);
748
    if (rc < 0) {
757
    if (rc < 0) {
749
        printf(NAME ": Unable to register driver (%d)\n", rc);
758
        printf(NAME ": Unable to register driver (%d)\n", rc);
750
        async_serialize_end();
-
 
751
        return false;
759
        return false;
752
    }
760
    }
753
   
761
   
754
    /* Initialize gcons */
762
    /* Initialize gcons */
755
    gcons_init(fb_info.phone);
763
    gcons_init(fb_info.phone);
Line 781... Line 789...
781
    for (i = 0; i < CONSOLE_COUNT; i++) {
789
    for (i = 0; i < CONSOLE_COUNT; i++) {
782
        if (i != KERNEL_CONSOLE) {
790
        if (i != KERNEL_CONSOLE) {
783
            if (screenbuffer_init(&consoles[i].scr,
791
            if (screenbuffer_init(&consoles[i].scr,
784
                fb_info.cols, fb_info.rows) == NULL) {
792
                fb_info.cols, fb_info.rows) == NULL) {
785
                printf(NAME ": Unable to allocate screen buffer %u\n", i);
793
                printf(NAME ": Unable to allocate screen buffer %u\n", i);
786
                async_serialize_end();
-
 
787
                return false;
794
                return false;
788
            }
795
            }
789
            screenbuffer_clear(&consoles[i].scr);
796
            screenbuffer_clear(&consoles[i].scr);
790
            keybuffer_init(&consoles[i].keybuffer);
797
            keybuffer_init(&consoles[i].keybuffer);
791
            consoles[i].index = i;
798
            consoles[i].index = i;
Line 795... Line 802...
795
            snprintf(vc, MAX_DEVICE_NAME, "vc%u", i);
802
            snprintf(vc, MAX_DEVICE_NAME, "vc%u", i);
796
           
803
           
797
            if (devmap_device_register(vc, &consoles[i].dev_handle) != EOK) {
804
            if (devmap_device_register(vc, &consoles[i].dev_handle) != EOK) {
798
                devmap_hangup_phone(DEVMAP_DRIVER);
805
                devmap_hangup_phone(DEVMAP_DRIVER);
799
                printf(NAME ": Unable to register device %s\n", vc);
806
                printf(NAME ": Unable to register device %s\n", vc);
800
                async_serialize_end();
-
 
801
                return false;
807
                return false;
802
            }
808
            }
803
        }
809
        }
804
    }
810
    }
805
   
811
   
806
    /* Disable kernel output to the console */
812
    /* Disable kernel output to the console */
807
    __SYSCALL0(SYS_DEBUG_DISABLE_CONSOLE);
813
    __SYSCALL0(SYS_DEBUG_DISABLE_CONSOLE);
808
   
814
   
809
    /* Initialize the screen */
815
    /* Initialize the screen */
-
 
816
    async_serialize_start();
810
    gcons_redraw_console();
817
    gcons_redraw_console();
811
    set_rgb_color(DEFAULT_FOREGROUND, DEFAULT_BACKGROUND);
818
    set_rgb_color(DEFAULT_FOREGROUND, DEFAULT_BACKGROUND);
812
    screen_clear();
819
    screen_clear();
813
    curs_goto(0, 0);
820
    curs_goto(0, 0);
814
    curs_visibility(active_console->scr.is_cursor_visible);
821
    curs_visibility(active_console->scr.is_cursor_visible);
-
 
822
    async_serialize_end();
815
   
823
   
816
    /* Receive kernel notifications */
824
    /* Receive kernel notifications */
817
    if (event_subscribe(EVENT_KCONSOLE, 0) != EOK)
825
    if (event_subscribe(EVENT_KCONSOLE, 0) != EOK)
818
        printf(NAME ": Error registering kconsole notifications\n");
826
        printf(NAME ": Error registering kconsole notifications\n");
819
   
827
   
820
    async_set_interrupt_received(interrupt_received);
828
    async_set_interrupt_received(interrupt_received);
821
   
829
   
822
    async_serialize_end();
-
 
823
    return true;
830
    return true;
824
}
831
}
825
 
832
 
826
int main(int argc, char *argv[])
833
int main(int argc, char *argv[])
827
{
834
{