source: rtems/cpukit/libmisc/mouse/mouse_parser.c @ 03b5096

4.115
Last change on this file since 03b5096 was 03b5096, checked in by Joel Sherrill <joel.sherrill@…>, on 03/14/11 at 18:17:28

2011-03-14 Joel Sherrill <joel.sherrill@…>

  • libmisc/mouse/mouse_parser.c, libmisc/mouse/serial_mouse.c: Remove include of bsp.h
  • Property mode set to 100644
File size: 7.3 KB
Line 
1/*
2 * This code is derived from a UNIX Serial Port Mouse Driver with
3 * the following notice:
4 *
5 * ==================================================================
6 * Copyright (c) 1999 Greg Haerr <greg@censoft.com>
7 * Portions Copyright (c) 1991 David I. Bell
8 * Permission is granted to use, distribute, or modify this source,
9 * provided that this copyright notice remains intact.
10 *
11 * UNIX Serial Port Mouse Driver
12 *
13 * This driver opens a serial port directly, and interprets serial data.
14 * Microsoft, PC, Logitech and PS/2 mice are supported.  The PS/2 mouse
15 * is only supported if the OS runs the mouse byte codes through the
16 * serial port.
17 *
18 * Mouse Types Supported: pc  ms, logi, ps2
19 * ==================================================================
20 *
21 * It has been modified to support the concept of being just a parser
22 * fed data from an arbitrary source.  It is independent of either
23 * a PS/2 driver or a serial port.
24 *
25 * It was moved to cpukit/libmisc/mouse by Joel Sherrill.
26 *
27 * $Id$
28 */
29
30#include <stdio.h>
31#include <stdlib.h>
32#include <string.h>  /* strcmp */
33#include <unistd.h>
34#include <fcntl.h>
35#include <errno.h>
36
37#include <rtems.h>
38#include <rtems/mouse_parser.h>
39#include <rtems/mw_uid.h>
40
41/* states for the mouse */
42#define IDLE   0  /* start of byte sequence */
43#define XSET   1  /* setting x delta */
44#define YSET   2  /* setting y delta */
45#define XADD   3  /* adjusting x delta */
46#define YADD   4  /* adjusting y delta */
47
48/* values in the bytes returned by the mouse for the buttons*/
49#define PC_LEFT_BUTTON   4
50#define PC_MIDDLE_BUTTON 2
51#define PC_RIGHT_BUTTON  1
52
53#define MS_LEFT_BUTTON   2
54#define MS_RIGHT_BUTTON  1
55
56#define PS2_CTRL_BYTE    0x08
57#define PS2_LEFT_BUTTON    1
58#define PS2_RIGHT_BUTTON  2
59
60/* Bit fields in the bytes sent by the mouse.*/
61#define TOP_FIVE_BITS      0xf8
62#define BOTTOM_THREE_BITS  0x07
63#define TOP_BIT            0x80
64#define SIXTH_BIT          0x40
65#define BOTTOM_TWO_BITS    0x03
66#define THIRD_FOURTH_BITS  0x0c
67#define BOTTOM_SIX_BITS    0x3f
68
69/* local data */
70static int     state;            /* IDLE, XSET, ... */
71static BUTTON  buttons;          /* current mouse buttons pressed*/
72static BUTTON  availbuttons;     /* which buttons are available */
73static COORD   xd;               /* change in x */
74static COORD   yd;               /* change in y */
75
76static int     left;             /* because the button values change */
77static int     middle;           /* between mice, the buttons are */
78static int     right;            /* redefined */
79
80static int     (*parse)( int );  /* parse routine */
81
82/* local routines*/
83static int ParsePC(int);    /* routine to interpret PC mouse */
84static int ParseMS(int);    /* routine to interpret MS mouse */
85static int ParsePS2(int);    /* routine to interpret PS/2 mouse */
86
87/*
88 * Open up the mouse device.
89 * Returns the fd if successful, or negative if unsuccessful.
90 */
91int mouse_parser_initialize(const char *type)
92{
93  /* set button bits and parse procedure*/
94  if (!strcmp(type, "pc") || !strcmp(type, "logi")) {
95    /* pc or logitech mouse*/
96    left = PC_LEFT_BUTTON;
97    middle = PC_MIDDLE_BUTTON;
98    right = PC_RIGHT_BUTTON;
99    parse = ParsePC;
100  } else if (strcmp(type, "ms") == 0) {
101    /* microsoft mouse*/
102    left = MS_LEFT_BUTTON;
103    right = MS_RIGHT_BUTTON;
104    middle = 0;
105    parse = ParseMS;
106  } else if (strcmp(type, "ps2") == 0) {
107    /* PS/2 mouse*/
108    left = PS2_LEFT_BUTTON;
109    right = PS2_RIGHT_BUTTON;
110    middle = 0;
111    parse = ParsePS2;
112  } else
113    return -1;
114
115  printk("Device: /dev/mouse -- mouse type is: %s\n", type );
116
117  /* initialize data*/
118  availbuttons = left | middle | right;
119  state = IDLE;
120  buttons = 0;
121  xd = 0;
122  yd = 0;
123  return 0;
124}
125
126/*
127 * Attempt to read bytes from the mouse and interpret them.
128 * Returns -1 on error, 0 if either no bytes were read or not enough
129 * was read for a complete state, or 1 if the new state was read.
130 * When a new state is read, the current buttons and x and y deltas
131 * are returned.  This routine does not block.
132 */
133int MOU_Data( int ch, COORD *dx, COORD *dy, COORD *dz, BUTTON *bptr)
134{
135  int b;
136
137  if ( !parse ) {
138    printk( "Mouse parser is not initialized!\n" );
139    return -1;
140  }
141
142  /*
143   * Loop over all the bytes read in the buffer, parsing them.
144   * When a complete state has been read, return the results,
145   * leaving further bytes in the buffer for later calls.
146   */
147  if ( (*parse)( ch ) ) {
148    *dx = xd;
149    *dy = yd;
150    *dz = 0;
151    b = 0;
152    if (buttons & left)
153      b |= LBUTTON;
154    if (buttons & right)
155      b |= RBUTTON;
156    if (buttons & middle)
157      b |= MBUTTON;
158    *bptr = b;
159    return 1;
160  }
161  return 0;
162}
163
164/*
165 * Input routine for PC mouse.
166 * Returns nonzero when a new mouse state has been completed.
167 */
168static int ParsePC(int byte)
169{
170  int  sign;      /* sign of movement */
171
172  switch (state) {
173    case IDLE:
174      if ((byte & TOP_FIVE_BITS) == TOP_BIT) {
175        buttons = ~byte & BOTTOM_THREE_BITS;
176        state = XSET;
177      }
178      break;
179
180    case XSET:
181      sign = 1;
182      if (byte > 127) {
183        byte = 256 - byte;
184        sign = -1;
185      }
186      xd = byte * sign;
187      state = YSET;
188      break;
189
190    case YSET:
191      sign = 1;
192      if (byte > 127) {
193        byte = 256 - byte;
194        sign = -1;
195      }
196      yd = -byte * sign;
197      state = XADD;
198      break;
199
200    case XADD:
201      sign = 1;
202      if (byte > 127) {
203        byte = 256 - byte;
204        sign = -1;
205      }
206      xd += byte * sign;
207      state = YADD;
208      break;
209
210    case YADD:
211      sign = 1;
212      if (byte > 127) {
213        byte = 256 - byte;
214        sign = -1;
215      }
216      yd -= byte * sign;
217      state = IDLE;
218      return 1;
219  }
220  return 0;
221}
222
223/*
224 * Input routine for Microsoft mouse.
225 * Returns nonzero when a new mouse state has been completed.
226 */
227static int ParseMS(int byte)
228{
229  switch (state) {
230    case IDLE:
231      if (byte & SIXTH_BIT) {
232        buttons = (byte >> 4) & BOTTOM_TWO_BITS;
233        yd = ((byte & THIRD_FOURTH_BITS) << 4);
234        xd = ((byte & BOTTOM_TWO_BITS) << 6);
235        state = XADD;
236      }
237      break;
238
239    case XADD:
240      xd |= (byte & BOTTOM_SIX_BITS);
241      state = YADD;
242      break;
243
244    case YADD:
245      yd |= (byte & BOTTOM_SIX_BITS);
246      state = IDLE;
247      if (xd > 127)
248        xd -= 256;
249      if (yd > 127)
250        yd -= 256;
251      return 1;
252  }
253  return 0;
254}
255
256/*
257 * Input routine for PS/2 mouse.
258 * Returns nonzero when a new mouse state has been completed.
259 */
260static int ParsePS2(int byte)
261{
262  switch (state) {
263    case IDLE:
264      if (byte & PS2_CTRL_BYTE) {
265        buttons = byte &
266          (PS2_LEFT_BUTTON|PS2_RIGHT_BUTTON);
267        state = XSET;
268      }
269      break;
270
271    case XSET:
272      if(byte > 127)
273        byte -= 256;
274      xd = byte;
275      state = YSET;
276      break;
277
278    case YSET:
279      if(byte > 127)
280        byte -= 256;
281      yd = -byte;
282      state = IDLE;
283      return 1;
284  }
285  return 0;
286}
287
288/* generic mouse parser */
289void mouse_parser_enqueue( unsigned char *buffer, size_t size )
290{
291  COORD dx;
292  COORD dy;
293  COORD dz;
294  BUTTON bptr;
295
296  while( size-- ) {
297    if ( MOU_Data( *buffer++, &dx, &dy, &dz, &bptr ) ) {
298       struct MW_UID_MESSAGE m;
299
300        m.type = MV_UID_REL_POS;
301        /* buttons definitons have been selected to match */
302        m.m.pos.btns = bptr;
303        m.m.pos.x  = dx;
304        m.m.pos.y  = dy;
305        m.m.pos.z  = dz;
306        /* printk( "Mouse: msg: dx=%d, dy=%d, btn=%X\n", dx, dy, bptr ); */
307        uid_send_message( &m );
308    }
309  }
310}
311
Note: See TracBrowser for help on using the repository browser.