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

Subversion Repositories or1k

[/] [or1k/] [tags/] [MW_0_8_9PRE7/] [mw/] [src/] [drivers/] [mou_ser.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 673 markom
/*
2
 * Copyright (c) 1999, 2000 Greg Haerr <greg@censoft.com>
3
 * Portions Copyright (c) 1991 David I. Bell
4
 * Permission is granted to use, distribute, or modify this source,
5
 * provided that this copyright notice remains intact.
6
 *
7
 * UNIX Serial Port Mouse Driver
8
 *
9
 * This driver opens a serial port directly, and interprets serial data.
10
 * Microsoft, PC, Logitech and PS/2 mice are supported.
11
 * The PS/2 mouse is supported by using the /dev/psaux device.
12
 *
13
 * The following environment variables control the mouse type expected
14
 * and the serial port to open.
15
 *
16
 * Environment Var      Default         Allowed
17
 * MOUSE_TYPE           pc              ms, pc, logi, ps2
18
 * MOUSE_PORT           /dev/ttyS1      any serial port or /dev/psaux
19
 */
20
#include <stdio.h>
21
#include <stdlib.h>
22
#include <unistd.h>
23
#include <errno.h>
24
#include <fcntl.h>
25
#include <string.h>
26
#include "device.h"
27
 
28
#define TERMIOS         1       /* set to use termios serial port control*/
29
#define SGTTY           0        /* set to use sgtty serial port control*/
30
 
31
#define SCALE           3       /* default scaling factor for acceleration */
32
#define THRESH          5       /* default threshhold for acceleration */
33
 
34
#if TERMIOS
35
#include <termios.h>
36
#endif
37
#if SGTTY
38
#include <sgtty.h>
39
#endif
40
 
41
/* default settings*/
42
#if _MINIX
43
#define MOUSE_PORT      "/dev/mouse"
44
#define MOUSE_TYPE      "ms"
45
#else
46
#if ELKS
47
#define MOUSE_PORT      "/dev/ttys0"    /* default mouse tty port */
48
#else
49
#define MOUSE_PORT      "/dev/ttyS1"    /* default mouse tty port */
50
#endif
51
#define MOUSE_TYPE      "pc"            /* default mouse type "ms","pc","ps2" */
52
#endif
53
#define MAX_BYTES       128             /* number of bytes for buffer */
54
 
55
/* states for the mouse*/
56
#define IDLE                    0                /* start of byte sequence */
57
#define XSET                    1               /* setting x delta */
58
#define YSET                    2               /* setting y delta */
59
#define XADD                    3               /* adjusting x delta */
60
#define YADD                    4               /* adjusting y delta */
61
 
62
/* values in the bytes returned by the mouse for the buttons*/
63
#define PC_LEFT_BUTTON          4
64
#define PC_MIDDLE_BUTTON        2
65
#define PC_RIGHT_BUTTON         1
66
 
67
#define MS_LEFT_BUTTON          2
68
#define MS_RIGHT_BUTTON         1
69
 
70
#define PS2_CTRL_BYTE           0x08
71
#define PS2_LEFT_BUTTON         1
72
#define PS2_RIGHT_BUTTON        2
73
 
74
/* Bit fields in the bytes sent by the mouse.*/
75
#define TOP_FIVE_BITS           0xf8
76
#define BOTTOM_THREE_BITS       0x07
77
#define TOP_BIT                 0x80
78
#define SIXTH_BIT               0x40
79
#define BOTTOM_TWO_BITS         0x03
80
#define THIRD_FOURTH_BITS       0x0c
81
#define BOTTOM_SIX_BITS         0x3f
82
 
83
/* local data*/
84
static int              mouse_fd;       /* file descriptor for mouse */
85
static int              state;          /* IDLE, XSET, ... */
86
static int              buttons;        /* current mouse buttons pressed*/
87
static int              availbuttons;   /* which buttons are available */
88
static MWCOORD          xd;             /* change in x */
89
static MWCOORD          yd;             /* change in y */
90
 
91
static int              left;           /* because the button values change */
92
static int              middle;         /* between mice, the buttons are */
93
static int              right;          /* redefined */
94
 
95
static unsigned char    *bp;            /* buffer pointer */
96
static int              nbytes;         /* number of bytes left */
97
static unsigned char    buffer[MAX_BYTES];      /* data bytes read */
98
static int              (*parse)();     /* parse routine */
99
 
100
/* local routines*/
101
static int      MOU_Open(MOUSEDEVICE *pmd);
102
static void     MOU_Close(void);
103
static int      MOU_GetButtonInfo(void);
104
static void     MOU_GetDefaultAccel(int *pscale,int *pthresh);
105
static int      MOU_Read(MWCOORD *dx, MWCOORD *dy, MWCOORD *dz, int *bptr);
106
static int      MOU_Poll(void);
107
static int      ParsePC(int);           /* routine to interpret PC mouse */
108
static int      ParseMS(int);           /* routine to interpret MS mouse */
109
static int      ParsePS2(int);          /* routine to interpret PS/2 mouse */
110
 
111
MOUSEDEVICE mousedev = {
112
        MOU_Open,
113
        MOU_Close,
114
        MOU_GetButtonInfo,
115
        MOU_GetDefaultAccel,
116
        MOU_Read,
117
#if _MINIX
118
        MOU_Poll
119
#else
120
        NULL
121
#endif
122
};
123
 
124
/*
125
 * Open up the mouse device.
126
 * Returns the fd if successful, or negative if unsuccessful.
127
 */
128
static int
129
MOU_Open(MOUSEDEVICE *pmd)
130
{
131
        char    *type;
132
        char    *port;
133
        struct termios termios;
134
 
135
        /* get mouse type and port*/
136
        if( !(type = getenv("MOUSE_TYPE")))
137
                type = MOUSE_TYPE;
138
 
139
        if( !(port = getenv("MOUSE_PORT")))
140
                port = MOUSE_PORT;
141
 
142
        /* set button bits and parse procedure*/
143
        if(!strcmp(type, "pc") || !strcmp(type, "logi")) {
144
                /* pc or logitech mouse*/
145
                left = PC_LEFT_BUTTON;
146
                middle = PC_MIDDLE_BUTTON;
147
                right = PC_RIGHT_BUTTON;
148
                parse = ParsePC;
149
        } else if (strcmp(type, "ms") == 0) {
150
                /* microsoft mouse*/
151
                left = MS_LEFT_BUTTON;
152
                right = MS_RIGHT_BUTTON;
153
                middle = 0;
154
                parse = ParseMS;
155
        } else if (strcmp(type, "ps2") == 0) {
156
                /* PS/2 mouse*/
157
                left = PS2_LEFT_BUTTON;
158
                right = PS2_RIGHT_BUTTON;
159
                middle = 0;
160
                parse = ParsePS2;
161
        } else
162
                return -1;
163
 
164
        /* open mouse port*/
165
        mouse_fd = open(port, O_NONBLOCK);
166
        if (mouse_fd < 0) {
167
                EPRINTF("Error %d opening serial mouse type %s on port %s.\n",
168
                        errno, type, port);
169
                return -1;
170
        }
171
 
172
#if SGTTY
173
        /* set rawmode serial port using sgtty*/
174
        struct sgttyb sgttyb;
175
 
176
        if (ioctl(fd, TIOCGETP, &sgttyb) == -1)
177
                goto err;
178
        sgttyb.sg_flags |= RAW;
179
        sgttyb.sg_flags &= ~(EVENP | ODDP | ECHO | XTABS | CRMOD);
180
 
181
        if (ioctl(fd, TIOCSETP, &sgttyb) == -1)
182
                goto err;
183
        if (ioctl(fd, TIOCFLUSH, 0) < 0)
184
                goto err;
185
#endif
186
 
187
#if TERMIOS
188
        /*
189
         * Note we don't check success for the tcget/setattr calls,
190
         * some kernels don't support them for certain devices
191
         * (like /dev/psaux).
192
         */
193
 
194
        /* set rawmode serial port using termios*/
195
        tcgetattr(mouse_fd, &termios);
196
 
197
        /* These functions appear to be broken in ELKS Dev86 */
198
        if(cfgetispeed(&termios) != B1200)
199
                cfsetispeed(&termios, B1200);
200
#if _MINIX
201
        if(cfgetospeed(&termios) != B1200)
202
                cfsetospeed(&termios, B1200);
203
#endif
204
 
205
#if !_MINIX
206
        termios.c_cflag &= ~CBAUD;
207
        termios.c_cflag |= B1200;
208
#endif
209
        termios.c_lflag &= ~(ECHO | ECHONL | ICANON | IEXTEN | ISIG);
210
        termios.c_iflag &= ~(ICRNL | INPCK | ISTRIP | IXON | BRKINT | IGNBRK);
211
        termios.c_cflag &= ~(CSIZE | PARENB);
212
        termios.c_cflag |= CS8;
213
        termios.c_cc[VMIN] = 0;
214
        termios.c_cc[VTIME] = 0;
215
 
216
        tcsetattr(mouse_fd, TCSAFLUSH, &termios);
217
#endif /* TERMIOS*/
218
 
219
        /* initialize data*/
220
        availbuttons = left | middle | right;
221
        state = IDLE;
222
        nbytes = 0;
223
        buttons = 0;
224
        xd = 0;
225
        yd = 0;
226
        return mouse_fd;
227
err:
228
        close(mouse_fd);
229
        mouse_fd = 0;
230
        return -1;
231
}
232
 
233
/*
234
 * Close the mouse device.
235
 */
236
static void
237
MOU_Close(void)
238
{
239
        if (mouse_fd > 0) {
240
                close(mouse_fd);
241
        }
242
        mouse_fd = 0;
243
}
244
 
245
/*
246
 * Get mouse buttons supported
247
 */
248
static int
249
MOU_GetButtonInfo(void)
250
{
251
        return availbuttons;
252
}
253
 
254
/*
255
 * Get default mouse acceleration settings
256
 */
257
static void
258
MOU_GetDefaultAccel(int *pscale,int *pthresh)
259
{
260
        *pscale = SCALE;
261
        *pthresh = THRESH;
262
}
263
 
264
/*
265
 * Attempt to read bytes from the mouse and interpret them.
266
 * Returns -1 on error, 0 if either no bytes were read or not enough
267
 * was read for a complete state, or 1 if the new state was read.
268
 * When a new state is read, the current buttons and x and y deltas
269
 * are returned.  This routine does not block.
270
 */
271
static int
272
MOU_Read(MWCOORD *dx, MWCOORD *dy, MWCOORD *dz, int *bptr)
273
{
274
        int     b;
275
 
276
        /*
277
         * If there are no more bytes left, then read some more,
278
         * waiting for them to arrive.  On a signal or a non-blocking
279
         * error, return saying there is no new state available yet.
280
         */
281
        if (nbytes <= 0) {
282
                bp = buffer;
283
                nbytes = read(mouse_fd, bp, MAX_BYTES);
284
                if (nbytes < 0) {
285
                        if (errno == EINTR || errno == EAGAIN)
286
                                return 0;
287
#if _MINIX
288
                        return 0;
289
#else
290
                        return -1;
291
#endif
292
                }
293
        }
294
 
295
        /*
296
         * Loop over all the bytes read in the buffer, parsing them.
297
         * When a complete state has been read, return the results,
298
         * leaving further bytes in the buffer for later calls.
299
         */
300
        while (nbytes-- > 0) {
301
                if ((*parse)((int) *bp++)) {
302
                        *dx = xd;
303
                        *dy = yd;
304
                        *dz = 0;
305
                        b = 0;
306
                        if(buttons & left)
307
                                b |= MWBUTTON_L;
308
                        if(buttons & right)
309
                                b |= MWBUTTON_R;
310
                        if(buttons & middle)
311
                                b |= MWBUTTON_M;
312
                        *bptr = b;
313
                        return 1;
314
                }
315
        }
316
        return 0;
317
}
318
 
319
/*
320
 * Input routine for PC mouse.
321
 * Returns nonzero when a new mouse state has been completed.
322
 */
323
static int
324
ParsePC(int byte)
325
{
326
        int     sign;                   /* sign of movement */
327
 
328
        switch (state) {
329
                case IDLE:
330
                        if ((byte & TOP_FIVE_BITS) == TOP_BIT) {
331
                                buttons = ~byte & BOTTOM_THREE_BITS;
332
                                state = XSET;
333
                        }
334
                        break;
335
 
336
                case XSET:
337
                        sign = 1;
338
                        if (byte > 127) {
339
                                byte = 256 - byte;
340
                                sign = -1;
341
                        }
342
                        xd = byte * sign;
343
                        state = YSET;
344
                        break;
345
 
346
                case YSET:
347
                        sign = 1;
348
                        if (byte > 127) {
349
                                byte = 256 - byte;
350
                                sign = -1;
351
                        }
352
                        yd = -byte * sign;
353
                        state = XADD;
354
                        break;
355
 
356
                case XADD:
357
                        sign = 1;
358
                        if (byte > 127) {
359
                                byte = 256 - byte;
360
                                sign = -1;
361
                        }
362
                        xd += byte * sign;
363
                        state = YADD;
364
                        break;
365
 
366
                case YADD:
367
                        sign = 1;
368
                        if (byte > 127) {
369
                                byte = 256 - byte;
370
                                sign = -1;
371
                        }
372
                        yd -= byte * sign;
373
                        state = IDLE;
374
                        return 1;
375
        }
376
        return 0;
377
}
378
 
379
 
380
/*
381
 * Input routine for Microsoft mouse.
382
 * Returns nonzero when a new mouse state has been completed.
383
 */
384
static int
385
ParseMS(int byte)
386
{
387
        switch (state) {
388
                case IDLE:
389
                        if (byte & SIXTH_BIT) {
390
                                buttons = (byte >> 4) & BOTTOM_TWO_BITS;
391
                                yd = ((byte & THIRD_FOURTH_BITS) << 4);
392
                                xd = ((byte & BOTTOM_TWO_BITS) << 6);
393
                                state = XADD;
394
                        }
395
                        break;
396
 
397
                case XADD:
398
                        xd |= (byte & BOTTOM_SIX_BITS);
399
                        state = YADD;
400
                        break;
401
 
402
                case YADD:
403
                        yd |= (byte & BOTTOM_SIX_BITS);
404
                        state = IDLE;
405
                        if (xd > 127)
406
                                xd -= 256;
407
                        if (yd > 127)
408
                                yd -= 256;
409
                        return 1;
410
        }
411
        return 0;
412
}
413
 
414
/*
415
 * Input routine for PS/2 mouse.
416
 * Returns nonzero when a new mouse state has been completed.
417
 */
418
static int
419
ParsePS2(int byte)
420
{
421
        switch (state) {
422
                case IDLE:
423
                        if (byte & PS2_CTRL_BYTE) {
424
                                buttons = byte &
425
                                        (PS2_LEFT_BUTTON|PS2_RIGHT_BUTTON);
426
                                state = XSET;
427
                        }
428
                        break;
429
 
430
                case XSET:
431
                        if(byte > 127)
432
                                byte -= 256;
433
                        xd = byte;
434
                        state = YSET;
435
                        break;
436
 
437
                case YSET:
438
                        if(byte > 127)
439
                                byte -= 256;
440
                        yd = -byte;
441
                        state = IDLE;
442
                        return 1;
443
        }
444
        return 0;
445
}
446
 
447
static int
448
MOU_Poll(void)
449
{
450
        return 1;       /* used by _MINIX only*/
451
}
452
 
453
/*  #define TEST 1  */
454
#if TEST
455
main()
456
{
457
        MWCOORD x, y, z;
458
        int     b;
459
 
460
        DPRINTF("Open Mouse\n");
461
        if( MOU_Open(0) < 0)
462
                DPRINTF("open failed mouse\n" );
463
 
464
        while(1)
465
        {
466
                if(MOU_Read(&x, &y, &z, &b) == 1)
467
                {
468
                        DPRINTF("%d,%d,%d\n", x, y, b);
469
                }
470
        }
471
}
472
#endif

powered by: WebSVN 2.1.0

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