OpenCores
URL https://opencores.org/ocsvn/or1k_old/or1k_old/trunk

Subversion Repositories or1k_old

[/] [or1k_old/] [trunk/] [rc203soc/] [sw/] [uClinux/] [arch/] [armnommu/] [drivers/] [char/] [selection.c] - Blame information for rev 1782

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1622 jcastillo
/*
2
 * linux/arch/arm/drivers/char/console/selection.c
3
 *
4
 * This module exports the functions:
5
 *
6
 *     'int set_selection(const unsigned long arg)'
7
 *     'void clear_selection(void)'
8
 *     'int paste_selection(struct tty_struct *tty)'
9
 *     'int sel_loadlut(const unsigned long arg)'
10
 *
11
 * Now that /dev/vcs exists, most of this can disappear again.
12
 */
13
 
14
#include <linux/tty.h>
15
#include <linux/sched.h>
16
#include <linux/mm.h>
17
#include <linux/malloc.h>
18
#include <linux/types.h>
19
 
20
#include <asm/segment.h>
21
 
22
#include "vt_kern.h"
23
#include "consolemap.h"
24
#include "selection.h"
25
 
26
#ifndef MIN
27
#define MIN(a,b)        ((a) < (b) ? (a) : (b))
28
#endif
29
 
30
/* Don't take this from <ctype.h>: 011-015 in the buffer aren't spaces */
31
#define isspace(c)      ((c) == ' ')
32
 
33
#define sel_pos(n)      inverse_translate(scrw2glyph(screen_word(vtdata.select.vt, n)))
34
 
35
/*
36
 * clear_selection, highlight and highlight_pointer can be called
37
 * from interrupt (via scrollback/front)
38
 */
39
 
40
/*
41
 * set reverse video on characters s-e of console with selection.
42
 */
43
static inline void highlight (const int s, const int e)
44
{
45
        invert_screen(vtdata.select.vt, s, e - s);
46
}
47
 
48
/*
49
 * use complementary color to show the pointer
50
 */
51
static inline void highlight_pointer (int where)
52
{
53
        complement_pos(vtdata.select.vt, where);
54
}
55
 
56
/*
57
 * Remove the current selection highlight, if any,
58
 * from the console holding selection.
59
 */
60
void clear_selection (void)
61
{
62
        highlight_pointer(-1); /* hide the pointer */
63
        if (vtdata.select.start != -1) {
64
                highlight(vtdata.select.start, vtdata.select.end);
65
                vtdata.select.start = -1;
66
        }
67
}
68
 
69
/*
70
 * User settable table: what characters are to be considered alphabetic?
71
 * 256 bits
72
 */
73
static u32 inwordLut[8]={
74
  0x00000000, /* control chars     */
75
  0x03FF0000, /* digits            */
76
  0x87FFFFFE, /* uppercase and '_' */
77
  0x07FFFFFE, /* lowercase         */
78
  0x00000000,
79
  0x00000000,
80
  0xFF7FFFFF, /* latin-1 accented letters, not multiplication sign */
81
  0xFF7FFFFF  /* latin-1 accented letters, not division sign */
82
};
83
 
84
static inline int inword(const unsigned char c)
85
{
86
        return (inwordLut[c>>5] >> (c & 31)) & 1;
87
}
88
 
89
/*
90
 * set inwordLut contents.  Invoked by ioctl().
91
 */
92
int sel_loadlut(const unsigned long arg)
93
{
94
        int i = verify_area(VERIFY_READ, (char *) arg, 36);
95
        if (i)
96
                return i;
97
        memcpy_fromfs(inwordLut, (u32 *)(arg+4), 32);
98
        return 0;
99
}
100
 
101
/*
102
 * does buffer offset p correspond to character at LH/RH edge of screen?
103
 */
104
static inline int atedge(const int p)
105
{
106
        return (!(p % vtdata.numcolumns) || !((p + 1) % vtdata.numcolumns));
107
}
108
 
109
/*
110
 * constrain v such that v <= u
111
 */
112
static inline int limit (const int v, const int u)
113
{
114
        return ((v > u) ? u : v);
115
}
116
 
117
/*
118
 * set the current selection.  Invoked by ioctl().
119
 */
120
int set_selection (const unsigned long arg, struct tty_struct *tty)
121
{
122
    struct vt * vt = vtdata.fgconsole;
123
    int sel_mode, new_sel_start, new_sel_end, spc;
124
    char *bp, *obp;
125
    int i, ps, pe;
126
 
127
    vt_do_unblankscreen ();
128
 
129
    {
130
        unsigned short *args, xs, ys, xe, ye;
131
 
132
        args = (unsigned short *)(arg + 1);
133
        xs = get_user (args ++) - 1;
134
        ys = get_user (args ++) - 1;
135
        xe = get_user (args ++) - 1;
136
        ye = get_user (args ++) - 1;
137
        sel_mode = get_user (args);
138
 
139
        xs = limit (xs, vtdata.numcolumns - 1);
140
        ys = limit (ys, vtdata.numrows - 1);
141
        xe = limit (xe, vtdata.numcolumns - 1);
142
        ye = limit (ye, vtdata.numrows - 1);
143
        ps = ys * vtdata.numcolumns + xs;
144
        pe = ye * vtdata.numcolumns + xe;
145
 
146
        if (sel_mode == 4) {
147
            /* useful for screendump without selection highlights */
148
            clear_selection ();
149
            return 0;
150
        }
151
 
152
        if (vt->vcd->report_mouse && sel_mode & 16) {
153
            mouse_report (tty, sel_mode & 15, xs, ys);
154
            return 0;
155
        }
156
    }
157
 
158
    if (ps > pe) { /* make sel_start <= sel_end */
159
        ps ^= pe;
160
        pe ^= ps;
161
        ps ^= pe;
162
    }
163
 
164
    if (vt != vtdata.select.vt) {
165
        clear_selection ();
166
        vtdata.select.vt = vt;
167
    }
168
 
169
    switch (sel_mode) {
170
    case 0: /* character-by-character selection */
171
        new_sel_start = ps;
172
        new_sel_end = pe;
173
        break;
174
    case 1: /* word-by-word selection */
175
        spc = isspace (sel_pos (ps));
176
        for (new_sel_start = ps; ; ps --) {
177
            if (( spc && !isspace (sel_pos (ps))) ||
178
                (!spc && !inword (sel_pos (ps))))
179
                break;
180
            new_sel_start = ps;
181
            if (!(ps % vtdata.numcolumns))
182
                break;
183
        }
184
        spc = isspace (sel_pos (pe));
185
        for (new_sel_end = pe; ; pe ++) {
186
            if (( spc && !isspace (sel_pos (pe))) ||
187
                (!spc && !inword (sel_pos (pe))))
188
                break;
189
            new_sel_end = pe;
190
            if (!((pe + 1) % vtdata.numcolumns))
191
                break;
192
        }
193
        break;
194
    case 2: /* line-by-line selection */
195
        new_sel_start = ps - ps % vtdata.numcolumns;
196
        new_sel_end = pe + vtdata.numcolumns - pe % vtdata.numcolumns - 1;
197
        break;
198
    case 3:
199
        highlight_pointer (pe);
200
        return 0;
201
    default:
202
        return -EINVAL;
203
    }
204
 
205
    /* remove the pointer */
206
    highlight_pointer (-1);
207
 
208
    /* select to end of line if on trailing space */
209
    if (new_sel_end > new_sel_start && !atedge(new_sel_end) && isspace(sel_pos(new_sel_end))) {
210
        for (pe = new_sel_end + 1; ; pe ++)
211
            if (!isspace (sel_pos (pe)) || atedge (pe))
212
                break;
213
        if (isspace (sel_pos (pe)))
214
            new_sel_end = pe;
215
    }
216
    if (vtdata.select.start == -1)                      /* no current selection */
217
        highlight (new_sel_start, new_sel_end);
218
    else if (new_sel_start == vtdata.select.start) {
219
        if (new_sel_end == vtdata.select.end)           /* no action required */
220
            return 0;
221
        else if (new_sel_end > vtdata.select.end)       /* extend to right */
222
            highlight (vtdata.select.end + 1, new_sel_end);
223
        else                                            /* contract from right */
224
            highlight (new_sel_end + 1, vtdata.select.end);
225
    } else if (new_sel_end == vtdata.select.end) {
226
        if (new_sel_start < vtdata.select.start)        /* extend to left */
227
            highlight (new_sel_start, vtdata.select.start - 1);
228
        else                            /* contract from left */
229
            highlight (vtdata.select.start, new_sel_start - 1);
230
    } else {    /* some other case; start selection from scratch */
231
        clear_selection ();
232
        highlight (new_sel_start, new_sel_end);
233
    }
234
    vtdata.select.start = new_sel_start;
235
    vtdata.select.end = new_sel_end;
236
 
237
    if (vtdata.select.buffer)
238
        kfree (vtdata.select.buffer);
239
    vtdata.select.buffer = kmalloc (vtdata.select.end - vtdata.select.start + 1, GFP_KERNEL);
240
    if (!vtdata.select.buffer) {
241
        printk ("selection: kmalloc() failed\n");
242
        clear_selection ();
243
        return -ENOMEM;
244
    }
245
 
246
    obp = bp = vtdata.select.buffer;
247
    for (i = vtdata.select.start; i <= vtdata.select.end; i++) {
248
        *bp = sel_pos (i);
249
        if (!isspace (*bp++))
250
            obp = bp;
251
        if (!((i + 1) % vtdata.numcolumns)) {
252
            /* strip trailing blanks from line and add newline,
253
             * unless non-space at end of line.
254
             */
255
            if (obp != bp) {
256
                bp = obp;
257
                *bp++ = '\r';
258
            }
259
            obp = bp;
260
        }
261
    }
262
    vtdata.select.length = bp - vtdata.select.buffer;
263
    return 0;
264
}
265
 
266
/* Insert the contents of the selection buffer into the queue of the
267
 * tty associated with the current console. Invoked by ioctl().
268
 */
269
int paste_selection (struct tty_struct *tty)
270
{
271
        struct wait_queue wait = { current, NULL };
272
        struct vt_struct *vt = ((struct vt *)tty->driver_data)->vtd;
273
        char    *bp = vtdata.select.buffer;
274
        int     c = vtdata.select.length;
275
        int     l;
276
 
277
        if (!bp || !c)
278
                return 0;
279
        vt_do_unblankscreen ();
280
        add_wait_queue(&vt->paste_wait, &wait);
281
        do {
282
                current->state = TASK_INTERRUPTIBLE;
283
                if (test_bit(TTY_THROTTLED, &tty->flags)) {
284
                        schedule();
285
                        continue;
286
                }
287
                l = MIN(c, tty->ldisc.receive_room(tty));
288
                tty->ldisc.receive_buf(tty, bp, 0, l);
289
                c -= l;
290
                bp += l;
291
        } while (c);
292
        remove_wait_queue(&vt->paste_wait, &wait);
293
        current->state = TASK_RUNNING;
294
        return 0;
295
}
296
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.