~galfy/helenos/bird-port-mainline

« back to all changes in this revision

Viewing changes to kernel/genarch/src/srln/srln.c

  • Committer: Martin Decky
  • Date: 2009-08-04 11:19:19 UTC
  • Revision ID: martin@uranus.dsrg.hide.ms.mff.cuni.cz-20090804111919-evyclddlr3v5lhmp
Initial import

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (c) 2009 Jakub Jermar
 
3
 * All rights reserved.
 
4
 *
 
5
 * Redistribution and use in source and binary forms, with or without
 
6
 * modification, are permitted provided that the following conditions
 
7
 * are met:
 
8
 *
 
9
 * - Redistributions of source code must retain the above copyright
 
10
 *   notice, this list of conditions and the following disclaimer.
 
11
 * - Redistributions in binary form must reproduce the above copyright
 
12
 *   notice, this list of conditions and the following disclaimer in the
 
13
 *   documentation and/or other materials provided with the distribution.
 
14
 * - The name of the author may not be used to endorse or promote products
 
15
 *   derived from this software without specific prior written permission.
 
16
 *
 
17
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 
18
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 
19
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 
20
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 
21
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 
22
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 
23
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 
24
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 
25
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 
26
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
27
 */
 
28
 
 
29
/** @addtogroup genarch
 
30
 * @{
 
31
 */
 
32
/**
 
33
 * @file
 
34
 * @brief Serial line processing.
 
35
 */
 
36
 
 
37
#include <genarch/srln/srln.h>
 
38
#include <console/chardev.h>
 
39
#include <console/console.h>
 
40
#include <proc/thread.h>
 
41
#include <arch.h>
 
42
#include <string.h>
 
43
 
 
44
static indev_operations_t srln_raw_ops = {
 
45
        .poll = NULL
 
46
};
 
47
 
 
48
static void ksrln(void *arg)
 
49
{
 
50
        srln_instance_t *instance = (srln_instance_t *) arg;
 
51
        bool cr = false;
 
52
        uint32_t escape = 0;
 
53
        
 
54
        while (true) {
 
55
                wchar_t ch = indev_pop_character(&instance->raw);
 
56
                
 
57
                /* ANSI escape sequence processing */
 
58
                if (escape != 0) {
 
59
                        escape <<= 8;
 
60
                        escape |= ch & 0xff;
 
61
                        
 
62
                        if ((escape == 0x1b4f) || (escape == 0x1b5b) || (escape == 0x1b5b33))
 
63
                                continue;
 
64
                        
 
65
                        switch (escape) {
 
66
                        case 0x1b4f46:
 
67
                        case 0x1b5b46:
 
68
                                ch = U_END_ARROW;
 
69
                                escape = 0;
 
70
                                break;
 
71
                        case 0x1b4f48:
 
72
                        case 0x1b5b48:
 
73
                                ch = U_HOME_ARROW;
 
74
                                escape = 0;
 
75
                                break;
 
76
                        case 0x1b5b41:
 
77
                                ch = U_UP_ARROW;
 
78
                                escape = 0;
 
79
                                break;
 
80
                        case 0x1b5b42:
 
81
                                ch = U_DOWN_ARROW;
 
82
                                escape = 0;
 
83
                                break;
 
84
                        case 0x1b5b43:
 
85
                                ch = U_RIGHT_ARROW;
 
86
                                escape = 0;
 
87
                                break;
 
88
                        case 0x1b5b44:
 
89
                                ch = U_LEFT_ARROW;
 
90
                                escape = 0;
 
91
                                break;
 
92
                        case 0x1b5b337e:
 
93
                                ch = U_DELETE;
 
94
                                escape = 0;
 
95
                                break;
 
96
                        default:
 
97
                                escape = 0;
 
98
                        }
 
99
                }
 
100
                
 
101
                if (ch == 0x1b) {
 
102
                        escape = ch & 0xff;
 
103
                        continue;
 
104
                }
 
105
                
 
106
                /* Replace carriage return with line feed
 
107
                   and suppress any following line feed */
 
108
                if ((ch == '\n') && (cr)) {
 
109
                        cr = false;
 
110
                        continue;
 
111
                }
 
112
                
 
113
                if (ch == '\r') {
 
114
                        ch = '\n';
 
115
                        cr = true;
 
116
                } else
 
117
                        cr = false;
 
118
                
 
119
                /* Backspace */
 
120
                if (ch == 0x7f)
 
121
                        ch = '\b';
 
122
                
 
123
                indev_push_character(instance->sink, ch);
 
124
        }
 
125
}
 
126
 
 
127
srln_instance_t *srln_init(void)
 
128
{
 
129
        srln_instance_t *instance
 
130
            = malloc(sizeof(srln_instance_t), FRAME_ATOMIC);
 
131
        if (instance) {
 
132
                instance->thread
 
133
                        = thread_create(ksrln, (void *) instance, TASK, 0, "ksrln", false);
 
134
                
 
135
                if (!instance->thread) {
 
136
                        free(instance);
 
137
                        return NULL;
 
138
                }
 
139
                
 
140
                instance->sink = NULL;
 
141
                indev_initialize("srln", &instance->raw, &srln_raw_ops);
 
142
        }
 
143
        
 
144
        return instance;
 
145
}
 
146
 
 
147
indev_t *srln_wire(srln_instance_t *instance, indev_t *sink)
 
148
{
 
149
        ASSERT(instance);
 
150
        ASSERT(sink);
 
151
        
 
152
        instance->sink = sink;
 
153
        thread_ready(instance->thread);
 
154
        
 
155
        return &instance->raw;
 
156
}
 
157
 
 
158
/** @}
 
159
 */