Subversion Repositories HelenOS

Rev

Rev 3618 | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 3618 Rev 3742
1
/*
1
/*
2
 * Copyright (c) 2006 Ondrej Palkovsky
2
 * Copyright (c) 2006 Ondrej Palkovsky
3
 * Copyright (c) 2008 Martin Decky
3
 * Copyright (c) 2008 Martin Decky
4
 * Copyright (c) 2008 Pavel Rimsky
4
 * Copyright (c) 2008 Pavel Rimsky
5
 * All rights reserved.
5
 * All rights reserved.
6
 *
6
 *
7
 * Redistribution and use in source and binary forms, with or without
7
 * Redistribution and use in source and binary forms, with or without
8
 * modification, are permitted provided that the following conditions
8
 * modification, are permitted provided that the following conditions
9
 * are met:
9
 * are met:
10
 *
10
 *
11
 * - Redistributions of source code must retain the above copyright
11
 * - Redistributions of source code must retain the above copyright
12
 *   notice, this list of conditions and the following disclaimer.
12
 *   notice, this list of conditions and the following disclaimer.
13
 * - Redistributions in binary form must reproduce the above copyright
13
 * - Redistributions in binary form must reproduce the above copyright
14
 *   notice, this list of conditions and the following disclaimer in the
14
 *   notice, this list of conditions and the following disclaimer in the
15
 *   documentation and/or other materials provided with the distribution.
15
 *   documentation and/or other materials provided with the distribution.
16
 * - The name of the author may not be used to endorse or promote products
16
 * - The name of the author may not be used to endorse or promote products
17
 *   derived from this software without specific prior written permission.
17
 *   derived from this software without specific prior written permission.
18
 *
18
 *
19
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
 */
29
 */
30
 
30
 
31
/**
31
/**
32
 * @defgroup serial Serial console
32
 * @defgroup serial Serial console
33
 * @brief    Serial console services (putc, puts, clear screen, cursor goto,...)
33
 * @brief    Serial console services (putc, puts, clear screen, cursor goto,...)
34
 * @{
34
 * @{
35
 */
35
 */
36
 
36
 
37
/** @file
37
/** @file
38
 */
38
 */
39
 
39
 
40
#include <stdio.h>
40
#include <stdio.h>
-
 
41
#include <ipc/ipc.h>
-
 
42
#include <async.h>
-
 
43
#include <ipc/fb.h>
-
 
44
#include <bool.h>
-
 
45
#include <errno.h>
41
 
46
 
42
#include "serial_console.h"
47
#include "serial_console.h"
43
 
48
 
44
#define MAX_CONTROL 20
49
#define MAX_CONTROL 20
45
 
50
 
46
static uint32_t width;
51
static int width;
47
static uint32_t height;
52
static int height;
48
static putc_function_t putc_function;
53
static putc_function_t putc_function;
49
 
54
 
-
 
55
/* Allow only 1 connection */
-
 
56
static int client_connected = 0;
-
 
57
 
50
void serial_puts(char *str)
58
void serial_puts(char *str)
51
{
59
{
52
    while (*str)
60
    while (*str)
53
        putc_function(*(str++));
61
        putc_function(*(str++));
54
}
62
}
55
 
63
 
56
void serial_goto(const unsigned int row, const unsigned int col)
64
void serial_goto(const unsigned int row, const unsigned int col)
57
{
65
{
58
    if ((row > height) || (col > width))
66
    if ((row > height) || (col > width))
59
        return;
67
        return;
60
   
68
   
61
    char control[20];
69
    char control[20];
62
    snprintf(control, 20, "\033[%u;%uf", row + 1, col + 1);
70
    snprintf(control, 20, "\033[%u;%uf", row + 1, col + 1);
63
    serial_puts(control);
71
    serial_puts(control);
64
}
72
}
65
 
73
 
66
void serial_clrscr(void)
74
void serial_clrscr(void)
67
{
75
{
68
    serial_puts("\033[2J");
76
    serial_puts("\033[2J");
69
}
77
}
70
 
78
 
71
void serial_scroll(int i)
79
void serial_scroll(int i)
72
{
80
{
73
    if (i > 0) {
81
    if (i > 0) {
74
        serial_goto(height - 1, 0);
82
        serial_goto(height - 1, 0);
75
        while (i--)
83
        while (i--)
76
            serial_puts("\033D");
84
            serial_puts("\033D");
77
    } else if (i < 0) {
85
    } else if (i < 0) {
78
        serial_goto(0, 0);
86
        serial_goto(0, 0);
79
        while (i++)
87
        while (i++)
80
            serial_puts("\033M");
88
            serial_puts("\033M");
81
    }
89
    }
82
}
90
}
83
 
91
 
84
void serial_set_style(const unsigned int mode)
92
void serial_set_style(const unsigned int mode)
85
{
93
{
86
    char control[MAX_CONTROL];
94
    char control[MAX_CONTROL];
87
    snprintf(control, MAX_CONTROL, "\033[%um", mode);
95
    snprintf(control, MAX_CONTROL, "\033[%um", mode);
88
    serial_puts(control);
96
    serial_puts(control);
89
}
97
}
90
 
98
 
-
 
99
/** Set scrolling region. */
-
 
100
void serial_set_scroll_region(unsigned last_row)
-
 
101
{
-
 
102
    char control[MAX_CONTROL];
-
 
103
    snprintf(control, MAX_CONTROL, "\033[0;%ur", last_row);
-
 
104
    serial_puts(control);
-
 
105
}
-
 
106
 
91
void serial_cursor_disable(void)
107
void serial_cursor_disable(void)
92
{
108
{
93
    serial_puts("\033[?25l");
109
    serial_puts("\033[?25l");
94
}
110
}
95
 
111
 
96
void serial_cursor_enable(void)
112
void serial_cursor_enable(void)
97
{
113
{
98
    serial_puts("\033[?25h");
114
    serial_puts("\033[?25h");
99
}
115
}
100
 
116
 
101
void serial_console_init(putc_function_t putc_fn, uint32_t w, uint32_t h)
117
void serial_console_init(putc_function_t putc_fn, uint32_t w, uint32_t h)
102
{
118
{
103
    width = w;
119
    width = w;
104
    height = h;
120
    height = h;
105
    putc_function = putc_fn;
121
    putc_function = putc_fn;
106
}
122
}
-
 
123
 
-
 
124
/**
-
 
125
 * Main function of the thread serving client connections.
-
 
126
 */
-
 
127
void serial_client_connection(ipc_callid_t iid, ipc_call_t *icall)
-
 
128
{
-
 
129
    int retval;
-
 
130
    ipc_callid_t callid;
-
 
131
    ipc_call_t call;
-
 
132
    char c;
-
 
133
    int lastcol = 0;
-
 
134
    int lastrow = 0;
-
 
135
    int newcol;
-
 
136
    int newrow;
-
 
137
    int fgcolor;
-
 
138
    int bgcolor;
-
 
139
    int i;
-
 
140
   
-
 
141
    if (client_connected) {
-
 
142
        ipc_answer_0(iid, ELIMIT);
-
 
143
        return;
-
 
144
    }
-
 
145
   
-
 
146
    client_connected = 1;
-
 
147
    ipc_answer_0(iid, EOK);
-
 
148
   
-
 
149
    /* Clear the terminal, set scrolling region
-
 
150
       to 0 - height rows. */
-
 
151
    serial_clrscr();
-
 
152
    serial_goto(0, 0);
-
 
153
    serial_set_scroll_region(height);
-
 
154
   
-
 
155
    while (true) {
-
 
156
        callid = async_get_call(&call);
-
 
157
        switch (IPC_GET_METHOD(call)) {
-
 
158
        case IPC_M_PHONE_HUNGUP:
-
 
159
            client_connected = 0;
-
 
160
            ipc_answer_0(callid, EOK);
-
 
161
            return;
-
 
162
        case FB_PUTCHAR:
-
 
163
            c = IPC_GET_ARG1(call);
-
 
164
            newrow = IPC_GET_ARG2(call);
-
 
165
            newcol = IPC_GET_ARG3(call);
-
 
166
            if ((lastcol != newcol) || (lastrow != newrow))
-
 
167
                serial_goto(newrow, newcol);
-
 
168
            lastcol = newcol + 1;
-
 
169
            lastrow = newrow;
-
 
170
            (*putc_function)(c);
-
 
171
            retval = 0;
-
 
172
            break;
-
 
173
        case FB_CURSOR_GOTO:
-
 
174
            newrow = IPC_GET_ARG1(call);
-
 
175
            newcol = IPC_GET_ARG2(call);
-
 
176
            serial_goto(newrow, newcol);
-
 
177
            lastrow = newrow;
-
 
178
            lastcol = newcol;
-
 
179
            retval = 0;
-
 
180
            break;
-
 
181
        case FB_GET_CSIZE:
-
 
182
            ipc_answer_2(callid, EOK, height, width);
-
 
183
            continue;
-
 
184
        case FB_CLEAR:
-
 
185
            serial_clrscr();
-
 
186
            retval = 0;
-
 
187
            break;
-
 
188
        case FB_SET_STYLE:
-
 
189
            fgcolor = IPC_GET_ARG1(call);
-
 
190
            bgcolor = IPC_GET_ARG2(call);
-
 
191
            if (fgcolor < bgcolor)
-
 
192
                serial_set_style(0);
-
 
193
            else
-
 
194
                serial_set_style(7);
-
 
195
            retval = 0;
-
 
196
            break;
-
 
197
        case FB_SCROLL:
-
 
198
            i = IPC_GET_ARG1(call);
-
 
199
            if ((i > height) || (i < -height)) {
-
 
200
                retval = EINVAL;
-
 
201
                break;
-
 
202
            }
-
 
203
            serial_scroll(i);
-
 
204
            serial_goto(lastrow, lastcol);
-
 
205
            retval = 0;
-
 
206
            break;
-
 
207
        case FB_CURSOR_VISIBILITY:
-
 
208
            if(IPC_GET_ARG1(call))
-
 
209
                serial_cursor_enable();
-
 
210
            else
-
 
211
                serial_cursor_disable();
-
 
212
            retval = 0;
-
 
213
            break;
-
 
214
        default:
-
 
215
            retval = ENOENT;
-
 
216
        }
-
 
217
        ipc_answer_0(callid, retval);
-
 
218
    }
-
 
219
}
107
 
220
 
108
/**
221
/**
109
 * @}
222
 * @}
110
 */
223
 */
111
 
224