Subversion Repositories HelenOS

Rev

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

Rev 4542 Rev 4571
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
#include <fibril_sync.h>
56
 
55
 
57
#include "console.h"
56
#include "console.h"
58
#include "gcons.h"
57
#include "gcons.h"
59
#include "screenbuffer.h"
58
#include "screenbuffer.h"
Line 97... Line 96...
97
    size_t col;  /**< Leftmost column of the span. */
96
    size_t col;  /**< Leftmost column of the span. */
98
    size_t row;  /**< Row where the span lies. */
97
    size_t row;  /**< Row where the span lies. */
99
    size_t cnt;  /**< Width of the span. */
98
    size_t cnt;  /**< Width of the span. */
100
} fb_pending;
99
} fb_pending;
101
 
100
 
102
/** Pending input structure. */
-
 
103
typedef struct {
-
 
104
    link_t link;
-
 
105
    console_t *cons;      /**< Console waiting for input */
-
 
106
    ipc_callid_t rid;     /**< Call ID waiting for input */
-
 
107
    ipc_callid_t callid;  /**< Call ID waiting for IPC_DATA_READ */
-
 
108
   
-
 
109
    size_t pos;           /**< Position of the last stored data */
-
 
110
    size_t size;          /**< Size of ther buffer */
-
 
111
    char *data;           /**< Already stored data */
-
 
112
} pending_input_t;
-
 
113
 
-
 
114
LIST_INITIALIZE(pending_input);
-
 
115
 
-
 
116
static FIBRIL_MUTEX_INITIALIZE(input_mutex);
101
static FIBRIL_MUTEX_INITIALIZE(input_mutex);
117
static FIBRIL_CONDVAR_INITIALIZE(input_cv);
102
static FIBRIL_CONDVAR_INITIALIZE(input_cv);
118
static input_flag = false;
-
 
119
 
-
 
120
/** Process pending input requests */
-
 
121
static void process_pending_input(void)
-
 
122
{
-
 
123
    link_t *cur;
-
 
124
   
-
 
125
loop:
-
 
126
    fibril_mutex_lock(&input_mutex);
-
 
127
    while (!input_flag)
-
 
128
        fibril_condvar_wait(&input_cv, &input_mutex);
-
 
129
rescan:
-
 
130
    for (cur = pending_input.next; cur != &pending_input; cur = cur->next) {
-
 
131
        pending_input_t *pr = list_get_instance(cur, pending_input_t, link);
-
 
132
       
-
 
133
        console_event_t ev;
-
 
134
        if (keybuffer_pop(&pr->cons->keybuffer, &ev)) {
-
 
135
           
-
 
136
            if (pr->data != NULL) {
-
 
137
                if (ev.type == KEY_PRESS) {
-
 
138
                    pr->data[pr->pos] = ev.c;
-
 
139
                    pr->pos++;
-
 
140
                }
-
 
141
            } else {
-
 
142
                ipc_answer_4(pr->rid, EOK, ev.type, ev.key, ev.mods, ev.c);
-
 
143
                list_remove(cur);
-
 
144
                free(pr);
-
 
145
                goto rescan;
-
 
146
            }
-
 
147
        }
-
 
148
       
-
 
149
        if ((pr->data != NULL) && (pr->pos == pr->size)) {
-
 
150
            (void) ipc_data_read_finalize(pr->callid, pr->data, pr->size);
-
 
151
            ipc_answer_1(pr->rid, EOK, pr->size);
-
 
152
 
-
 
153
            free(pr->data);
-
 
154
            list_remove(cur);
-
 
155
            free(pr);
-
 
156
            goto rescan;
-
 
157
        }
-
 
158
    }
-
 
159
    input_flag = false;
-
 
160
    fibril_mutex_unlock(&input_mutex);
-
 
161
    goto loop;
-
 
162
}
-
 
163
 
103
 
164
static void curs_visibility(bool visible)
104
static void curs_visibility(bool visible)
165
{
105
{
166
    async_msg_1(fb_info.phone, FB_CURSOR_VISIBILITY, visible);
106
    async_msg_1(fb_info.phone, FB_CURSOR_VISIBILITY, visible);
167
}
107
}
Line 459... Line 399...
459
                break;
399
                break;
460
            }
400
            }
461
           
401
           
462
            fibril_mutex_lock(&input_mutex);
402
            fibril_mutex_lock(&input_mutex);
463
            keybuffer_push(&active_console->keybuffer, &ev);
403
            keybuffer_push(&active_console->keybuffer, &ev);
464
            input_flag = true;
-
 
465
            fibril_condvar_signal(&input_cv);
404
            fibril_condvar_broadcast(&input_cv);
466
            fibril_mutex_unlock(&input_mutex);
405
            fibril_mutex_unlock(&input_mutex);
467
            break;
406
            break;
468
        default:
407
        default:
469
            retval = ENOENT;
408
            retval = ENOENT;
470
        }
409
        }
Line 525... Line 464...
525
    }
464
    }
526
   
465
   
527
    size_t pos = 0;
466
    size_t pos = 0;
528
    console_event_t ev;
467
    console_event_t ev;
529
    fibril_mutex_lock(&input_mutex);
468
    fibril_mutex_lock(&input_mutex);
-
 
469
recheck:
530
    while ((keybuffer_pop(&cons->keybuffer, &ev)) && (pos < size)) {
470
    while ((keybuffer_pop(&cons->keybuffer, &ev)) && (pos < size)) {
531
        if (ev.type == KEY_PRESS) {
471
        if (ev.type == KEY_PRESS) {
532
            buf[pos] = ev.c;
472
            buf[pos] = ev.c;
533
            pos++;
473
            pos++;
534
        }
474
        }
Line 537... Line 477...
537
    if (pos == size) {
477
    if (pos == size) {
538
        (void) ipc_data_read_finalize(callid, buf, size);
478
        (void) ipc_data_read_finalize(callid, buf, size);
539
        ipc_answer_1(rid, EOK, size);
479
        ipc_answer_1(rid, EOK, size);
540
        free(buf);
480
        free(buf);
541
    } else {
481
    } else {
542
        pending_input_t *pr = (pending_input_t *) malloc(sizeof(pending_input_t));
-
 
543
        if (!pr) {
-
 
544
            fibril_mutex_unlock(&input_mutex);
482
        fibril_condvar_wait(&input_cv, &input_mutex);
545
            ipc_answer_0(callid, ENOMEM);
-
 
546
            ipc_answer_0(rid, ENOMEM);
-
 
547
            free(buf);
483
        goto recheck;
548
            return;
-
 
549
        }
-
 
550
       
-
 
551
        pr->cons = cons;
-
 
552
        pr->rid = rid;
-
 
553
        pr->callid = callid;
-
 
554
        pr->pos = pos;
-
 
555
        pr->size = size;
-
 
556
        pr->data = buf;
-
 
557
        list_append(&pr->link, &pending_input);
-
 
558
    }
484
    }
559
    fibril_mutex_unlock(&input_mutex);
485
    fibril_mutex_unlock(&input_mutex);
560
}
486
}
561
 
487
 
562
static void cons_get_event(console_t *cons, ipc_callid_t rid, ipc_call_t *request)
488
static void cons_get_event(console_t *cons, ipc_callid_t rid, ipc_call_t *request)
563
{
489
{
564
    console_event_t ev;
490
    console_event_t ev;
565
 
491
 
566
    fibril_mutex_lock(&input_mutex);
492
    fibril_mutex_lock(&input_mutex);
-
 
493
recheck:
567
    if (keybuffer_pop(&cons->keybuffer, &ev)) {
494
    if (keybuffer_pop(&cons->keybuffer, &ev)) {
568
        ipc_answer_4(rid, EOK, ev.type, ev.key, ev.mods, ev.c);
495
        ipc_answer_4(rid, EOK, ev.type, ev.key, ev.mods, ev.c);
569
    } else {
496
    } else {
570
        pending_input_t *pr = (pending_input_t *) malloc(sizeof(pending_input_t));
-
 
571
        if (!pr) {
-
 
572
            fibril_mutex_unlock(&input_mutex);
497
        fibril_condvar_wait(&input_cv, &input_mutex);
573
            ipc_answer_0(rid, ENOMEM);
-
 
574
            return;
498
        goto recheck;
575
        }
-
 
576
       
-
 
577
        pr->cons = cons;
-
 
578
        pr->rid = rid;
-
 
579
        pr->callid = 0;
-
 
580
        pr->data = NULL;
-
 
581
        list_append(&pr->link, &pending_input);
-
 
582
    }
499
    }
583
    fibril_mutex_unlock(&input_mutex);
500
    fibril_mutex_unlock(&input_mutex);
584
}
501
}
585
 
502
 
586
/** Default thread for new connections */
503
/** Default thread for new connections */
Line 735... Line 652...
735
        return false;
652
        return false;
736
    }
653
    }
737
   
654
   
738
    async_new_connection(phonehash, 0, NULL, keyboard_events);
655
    async_new_connection(phonehash, 0, NULL, keyboard_events);
739
 
656
 
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);
-
 
747
   
-
 
748
    /* Connect to framebuffer driver */
657
    /* Connect to framebuffer driver */
749
    fb_info.phone = ipc_connect_me_to_blocking(PHONE_NS, SERVICE_VIDEO, 0, 0);
658
    fb_info.phone = ipc_connect_me_to_blocking(PHONE_NS, SERVICE_VIDEO, 0, 0);
750
    if (fb_info.phone < 0) {
659
    if (fb_info.phone < 0) {
751
        printf(NAME ": Failed to connect to video service\n");
660
        printf(NAME ": Failed to connect to video service\n");
752
        return -1;
661
        return -1;