~jakub/helenos/ia64-revival

« back to all changes in this revision

Viewing changes to uspace/srv/hid/console/console.c

  • Committer: Jakub Jermar
  • Date: 2011-04-13 14:45:41 UTC
  • mfrom: (527.1.397 main-clone)
  • Revision ID: jakub@jermar.eu-20110413144541-x0j3r1zxqhsljx1o
MergeĀ mainlineĀ changes.

Show diffs side-by-side

added added

removed removed

Lines of Context:
33
33
 */
34
34
 
35
35
#include <libc.h>
36
 
#include <ipc/ipc.h>
37
36
#include <ipc/kbd.h>
38
37
#include <io/keycode.h>
39
38
#include <ipc/mouse.h>
40
39
#include <ipc/fb.h>
41
40
#include <ipc/services.h>
 
41
#include <ipc/ns.h>
42
42
#include <errno.h>
43
43
#include <ipc/console.h>
44
44
#include <unistd.h>
73
73
/** Information about framebuffer */
74
74
struct {
75
75
        int phone;           /**< Framebuffer phone */
76
 
        ipcarg_t cols;       /**< Framebuffer columns */
77
 
        ipcarg_t rows;       /**< Framebuffer rows */
78
 
        ipcarg_t color_cap;  /**< Color capabilities (FB_CCAP_xxx) */
 
76
        sysarg_t cols;       /**< Framebuffer columns */
 
77
        sysarg_t rows;       /**< Framebuffer rows */
 
78
        sysarg_t color_cap;  /**< Color capabilities (FB_CCAP_xxx) */
79
79
} fb_info;
80
80
 
81
81
typedef struct {
82
82
        size_t index;             /**< Console index */
83
83
        size_t refcount;          /**< Connection reference count */
84
 
        dev_handle_t dev_handle;  /**< Device handle */
 
84
        devmap_handle_t devmap_handle;  /**< Device handle */
85
85
        keybuffer_t keybuffer;    /**< Buffer for incoming keys. */
86
86
        screenbuffer_t scr;       /**< Screenbuffer for saving screen
87
87
                                       contents and related settings. */
100
100
 
101
101
/** Information on row-span yet unsent to FB driver. */
102
102
struct {
103
 
        ipcarg_t col;  /**< Leftmost column of the span. */
104
 
        ipcarg_t row;  /**< Row where the span lies. */
105
 
        ipcarg_t cnt;  /**< Width of the span. */
 
103
        sysarg_t col;  /**< Leftmost column of the span. */
 
104
        sysarg_t row;  /**< Row where the span lies. */
 
105
        sysarg_t cnt;  /**< Width of the span. */
106
106
} fb_pending;
107
107
 
108
108
static FIBRIL_MUTEX_INITIALIZE(input_mutex);
115
115
 
116
116
static void curs_hide_sync(void)
117
117
{
118
 
        ipc_call_sync_1_0(fb_info.phone, FB_CURSOR_VISIBILITY, false); 
 
118
        async_req_1_0(fb_info.phone, FB_CURSOR_VISIBILITY, false); 
119
119
}
120
120
 
121
 
static void curs_goto(ipcarg_t x, ipcarg_t y)
 
121
static void curs_goto(sysarg_t x, sysarg_t y)
122
122
{
123
123
        async_msg_2(fb_info.phone, FB_CURSOR_GOTO, x, y);
124
124
}
130
130
 
131
131
static void screen_yield(void)
132
132
{
133
 
        ipc_call_sync_0_0(fb_info.phone, FB_SCREEN_YIELD);
 
133
        async_req_0_0(fb_info.phone, FB_SCREEN_YIELD);
134
134
}
135
135
 
136
136
static void screen_reclaim(void)
137
137
{
138
 
        ipc_call_sync_0_0(fb_info.phone, FB_SCREEN_RECLAIM);
 
138
        async_req_0_0(fb_info.phone, FB_SCREEN_RECLAIM);
139
139
}
140
140
 
141
141
static void kbd_yield(void)
142
142
{
143
 
        ipc_call_sync_0_0(kbd_phone, KBD_YIELD);
 
143
        async_req_0_0(kbd_phone, KBD_YIELD);
144
144
}
145
145
 
146
146
static void kbd_reclaim(void)
147
147
{
148
 
        ipc_call_sync_0_0(kbd_phone, KBD_RECLAIM);
 
148
        async_req_0_0(kbd_phone, KBD_RECLAIM);
149
149
}
150
150
 
151
151
static void set_style(uint8_t style)
179
179
        }
180
180
}
181
181
 
182
 
static int ccap_fb_to_con(ipcarg_t ccap_fb, ipcarg_t *ccap_con)
 
182
static int ccap_fb_to_con(sysarg_t ccap_fb, sysarg_t *ccap_con)
183
183
{
184
184
        switch (ccap_fb) {
185
185
        case FB_CCAP_NONE:
202
202
}
203
203
 
204
204
/** Send an area of screenbuffer to the FB driver. */
205
 
static void fb_update_area(console_t *cons, ipcarg_t x0, ipcarg_t y0, ipcarg_t width, ipcarg_t height)
 
205
static void fb_update_area(console_t *cons, sysarg_t x0, sysarg_t y0, sysarg_t width, sysarg_t height)
206
206
{
207
207
        if (interbuffer) {
208
 
                ipcarg_t x;
209
 
                ipcarg_t y;
 
208
                sysarg_t x;
 
209
                sysarg_t y;
210
210
                
211
211
                for (y = 0; y < height; y++) {
212
212
                        for (x = 0; x < width; x++) {
236
236
 * the old span is flushed first.
237
237
 *
238
238
 */
239
 
static void cell_mark_changed(ipcarg_t col, ipcarg_t row)
 
239
static void cell_mark_changed(sysarg_t col, sysarg_t row)
240
240
{
241
241
        if (fb_pending.cnt != 0) {
242
242
                if ((col != fb_pending.col + fb_pending.cnt)
254
254
}
255
255
 
256
256
/** Print a character to the active VC with buffering. */
257
 
static void fb_putchar(wchar_t c, ipcarg_t col, ipcarg_t row)
 
257
static void fb_putchar(wchar_t c, sysarg_t col, sysarg_t row)
258
258
{
259
259
        async_msg_3(fb_info.phone, FB_PUTCHAR, c, col, row);
260
260
}
351
351
                set_attrs(&cons->scr.attrs);
352
352
                curs_visibility(false);
353
353
                
354
 
                ipcarg_t x;
355
 
                ipcarg_t y;
 
354
                sysarg_t x;
 
355
                sysarg_t y;
356
356
                int rc = 0;
357
357
                
358
358
                if (interbuffer) {
407
407
                int retval;
408
408
                console_event_t ev;
409
409
                
410
 
                switch (IPC_GET_METHOD(call)) {
 
410
                switch (IPC_GET_IMETHOD(call)) {
411
411
                case IPC_M_PHONE_HUNGUP:
412
412
                        /* TODO: Handle hangup */
413
413
                        return;
436
436
                default:
437
437
                        retval = ENOENT;
438
438
                }
439
 
                ipc_answer_0(callid, retval);
 
439
                async_answer_0(callid, retval);
440
440
        }
441
441
}
442
442
 
450
450
                
451
451
                int retval;
452
452
                
453
 
                switch (IPC_GET_METHOD(call)) {
 
453
                switch (IPC_GET_IMETHOD(call)) {
454
454
                case IPC_M_PHONE_HUNGUP:
455
455
                        /* TODO: Handle hangup */
456
456
                        return;
471
471
                        retval = ENOENT;
472
472
                }
473
473
 
474
 
                ipc_answer_0(callid, retval);
 
474
                async_answer_0(callid, retval);
475
475
        }
476
476
}
477
477
 
482
482
        int rc = async_data_write_accept(&buf, false, 0, 0, 0, &size);
483
483
        
484
484
        if (rc != EOK) {
485
 
                ipc_answer_0(rid, rc);
 
485
                async_answer_0(rid, rc);
486
486
                return;
487
487
        }
488
488
        
497
497
        async_serialize_end();
498
498
        
499
499
        gcons_notify_char(cons->index);
500
 
        ipc_answer_1(rid, EOK, size);
 
500
        async_answer_1(rid, EOK, size);
501
501
        
502
502
        free(buf);
503
503
}
507
507
        ipc_callid_t callid;
508
508
        size_t size;
509
509
        if (!async_data_read_receive(&callid, &size)) {
510
 
                ipc_answer_0(callid, EINVAL);
511
 
                ipc_answer_0(rid, EINVAL);
 
510
                async_answer_0(callid, EINVAL);
 
511
                async_answer_0(rid, EINVAL);
512
512
                return;
513
513
        }
514
514
        
515
515
        char *buf = (char *) malloc(size);
516
516
        if (buf == NULL) {
517
 
                ipc_answer_0(callid, ENOMEM);
518
 
                ipc_answer_0(rid, ENOMEM);
 
517
                async_answer_0(callid, ENOMEM);
 
518
                async_answer_0(rid, ENOMEM);
519
519
                return;
520
520
        }
521
521
        
533
533
        
534
534
        if (pos == size) {
535
535
                (void) async_data_read_finalize(callid, buf, size);
536
 
                ipc_answer_1(rid, EOK, size);
 
536
                async_answer_1(rid, EOK, size);
537
537
                free(buf);
538
538
        } else {
539
539
                fibril_condvar_wait(&input_cv, &input_mutex);
551
551
        
552
552
recheck:
553
553
        if (keybuffer_pop(&cons->keybuffer, &ev)) {
554
 
                ipc_answer_4(rid, EOK, ev.type, ev.key, ev.mods, ev.c);
 
554
                async_answer_4(rid, EOK, ev.type, ev.key, ev.mods, ev.c);
555
555
        } else {
556
556
                fibril_condvar_wait(&input_cv, &input_mutex);
557
557
                goto recheck;
570
570
                if (i == KERNEL_CONSOLE)
571
571
                        continue;
572
572
                
573
 
                if (consoles[i].dev_handle == (dev_handle_t) IPC_GET_ARG1(*icall)) {
 
573
                if (consoles[i].devmap_handle == (devmap_handle_t) IPC_GET_ARG1(*icall)) {
574
574
                        cons = &consoles[i];
575
575
                        break;
576
576
                }
577
577
        }
578
578
        
579
579
        if (cons == NULL) {
580
 
                ipc_answer_0(iid, ENOENT);
 
580
                async_answer_0(iid, ENOENT);
581
581
                return;
582
582
        }
583
583
        
584
584
        ipc_callid_t callid;
585
585
        ipc_call_t call;
586
 
        ipcarg_t arg1;
587
 
        ipcarg_t arg2;
588
 
        ipcarg_t arg3;
 
586
        sysarg_t arg1;
 
587
        sysarg_t arg2;
 
588
        sysarg_t arg3;
589
589
        
590
590
        int rc;
591
591
        
596
596
        cons->refcount++;
597
597
        
598
598
        /* Accept the connection */
599
 
        ipc_answer_0(iid, EOK);
 
599
        async_answer_0(iid, EOK);
600
600
        
601
601
        while (true) {
602
602
                async_serialize_end();
607
607
                arg2 = 0;
608
608
                arg3 = 0;
609
609
                
610
 
                switch (IPC_GET_METHOD(call)) {
 
610
                switch (IPC_GET_IMETHOD(call)) {
611
611
                case IPC_M_PHONE_HUNGUP:
612
612
                        cons->refcount--;
613
613
                        if (cons->refcount == 0)
656
656
                case CONSOLE_GET_COLOR_CAP:
657
657
                        rc = ccap_fb_to_con(fb_info.color_cap, &arg1);
658
658
                        if (rc != EOK) {
659
 
                                ipc_answer_0(callid, rc);
 
659
                                async_answer_0(callid, rc);
660
660
                                continue;
661
661
                        }
662
662
                        break;
700
700
                        change_console(kernel_console);
701
701
                        break;
702
702
                }
703
 
                ipc_answer_3(callid, EOK, arg1, arg2, arg3);
 
703
                async_answer_3(callid, EOK, arg1, arg2, arg3);
704
704
        }
705
705
}
706
706
 
725
725
        }
726
726
        
727
727
        /* NB: The callback connection is slotted for removal */
728
 
        ipcarg_t phonehash;
729
 
        if (ipc_connect_to_me(kbd_phone, SERVICE_CONSOLE, 0, 0, &phonehash) != 0) {
 
728
        if (async_connect_to_me(kbd_phone, SERVICE_CONSOLE, 0, 0, keyboard_events)
 
729
            != 0) {
730
730
                printf(NAME ": Failed to create callback from input device\n");
731
731
                return false;
732
732
        }
733
733
        
734
 
        async_new_connection(phonehash, 0, NULL, keyboard_events);
735
 
        
736
734
        /* Connect to mouse device */
737
735
        mouse_phone = -1;
738
736
        int mouse_fd = open("/dev/hid_in/mouse", O_RDONLY);
748
746
                goto skip_mouse;
749
747
        }
750
748
        
751
 
        if (ipc_connect_to_me(mouse_phone, SERVICE_CONSOLE, 0, 0, &phonehash) != 0) {
 
749
        if (async_connect_to_me(mouse_phone, SERVICE_CONSOLE, 0, 0, mouse_events)
 
750
            != 0) {
752
751
                printf(NAME ": Failed to create callback from mouse device\n");
753
752
                mouse_phone = -1;
754
753
                goto skip_mouse;
755
754
        }
756
755
        
757
 
        async_new_connection(phonehash, 0, NULL, mouse_events);
758
756
skip_mouse:
759
757
        
760
758
        /* Connect to framebuffer driver */
761
 
        fb_info.phone = ipc_connect_me_to_blocking(PHONE_NS, SERVICE_VIDEO, 0, 0);
 
759
        fb_info.phone = service_connect_blocking(SERVICE_VIDEO, 0, 0);
762
760
        if (fb_info.phone < 0) {
763
761
                printf(NAME ": Failed to connect to video service\n");
764
762
                return -1;
803
801
                if (i != KERNEL_CONSOLE) {
804
802
                        if (screenbuffer_init(&consoles[i].scr,
805
803
                            fb_info.cols, fb_info.rows) == NULL) {
806
 
                                printf(NAME ": Unable to allocate screen buffer %u\n", i);
 
804
                                printf(NAME ": Unable to allocate screen buffer %zu\n", i);
807
805
                                return false;
808
806
                        }
809
807
                        screenbuffer_clear(&consoles[i].scr);
812
810
                        consoles[i].refcount = 0;
813
811
                        
814
812
                        char vc[DEVMAP_NAME_MAXLEN + 1];
815
 
                        snprintf(vc, DEVMAP_NAME_MAXLEN, "%s/vc%u", NAMESPACE, i);
 
813
                        snprintf(vc, DEVMAP_NAME_MAXLEN, "%s/vc%zu", NAMESPACE, i);
816
814
                        
817
 
                        if (devmap_device_register(vc, &consoles[i].dev_handle) != EOK) {
818
 
                                devmap_hangup_phone(DEVMAP_DRIVER);
 
815
                        if (devmap_device_register(vc, &consoles[i].devmap_handle) != EOK) {
819
816
                                printf(NAME ": Unable to register device %s\n", vc);
820
817
                                return false;
821
818
                        }
835
832
        async_serialize_end();
836
833
        
837
834
        /* Receive kernel notifications */
 
835
        async_set_interrupt_received(interrupt_received);
838
836
        if (event_subscribe(EVENT_KCONSOLE, 0) != EOK)
839
837
                printf(NAME ": Error registering kconsole notifications\n");
840
838
        
841
 
        async_set_interrupt_received(interrupt_received);
842
 
        
843
839
        return true;
844
840
}
845
841