Subversion Repositories shark

Rev

Rev 105 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
105 pj 1
/*
2
 * Project: S.Ha.R.K.
3
 *
4
 * Coordinators:
5
 *   Giorgio Buttazzo    <giorgio@sssup.it>
6
 *   Paolo Gai           <pj@gandalf.sssup.it>
7
 *
8
 * Authors     :
9
 *   Paolo Gai           <pj@gandalf.sssup.it>
10
 *   Massimiliano Giorgi <massy@gandalf.sssup.it>
11
 *   Luca Abeni          <luca@gandalf.sssup.it>
12
 *   (see the web pages for full authors list)
13
 *
14
 * ReTiS Lab (Scuola Superiore S.Anna - Pisa - Italy)
15
 *
16
 * http://www.sssup.it
17
 * http://retis.sssup.it
18
 * http://shark.sssup.it
19
 */
20
 
21
/**
22
 ------------
723 giacomo 23
 CVS :        $Id: mouse.c,v 1.2 2004-06-03 09:51:45 giacomo Exp $
105 pj 24
 
25
 File:        $File$
723 giacomo 26
 Revision:    $Revision: 1.2 $
27
 Last update: $Date: 2004-06-03 09:51:45 $
105 pj 28
 ------------
29
 
30
 Author:        Gerardo Lamastra
31
 Date:  9/5/96
32
 
33
 Revision:      1.1b
34
 Last update: 14/apr/1999
35
 
36
 Serial mouse driver
37
 The mouse driver receives data from the serial RxServer()
38
 Then it processes the mouse packet and sets the variables
39
 representing the external mouse status.
40
 
41
**/
42
 
43
/*
44
 * Copyright (C) 2000 Paolo Gai
45
 *
46
 * This program is free software; you can redistribute it and/or modify
47
 * it under the terms of the GNU General Public License as published by
48
 * the Free Software Foundation; either version 2 of the License, or
49
 * (at your option) any later version.
50
 *
51
 * This program is distributed in the hope that it will be useful,
52
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
53
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
54
 * GNU General Public License for more details.
55
 *
56
 * You should have received a copy of the GNU General Public License
57
 * along with this program; if not, write to the Free Software
58
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
59
 *
60
 */
61
 
62
/* Revision 1.1                    
63
 * Author:      Massimiliano Giorgi
64
 *
65
 * -- added support for PS/2 mouse  
66
 *
67
 * Detailed changed from 1.0g:
68
 * -- now mouse.c use "virtual operation"
69
 * -- all procedure changed to use "virtual operation"
70
 * ("virtual operation" are indipendent of the phisical device that
71
 * is used to comunicate with mouse so it can handle serial mouse, ps/2 mouse)
72
 * (all changed marked with a "MG")
73
 */
74
 
75
/* Revision 1.1b
76
 * Author:      Massimiliano Giorgi
77
 *
78
 * Changed to compile on 3.2.0
79
 * -- added wcet time
80
 * -- RECEIVE ports now are STREAM ports
81
 */
82
 
83
/*
84
 * Changelog:
85
 * -- Added support for various serial mouse
86
 * -- Virtual operations changed
87
 * -- Added support for auto-pointer
88
 */
89
 
90
/*
91
 * auto-pointer functions now are into
92
 * mcurtxt.c and mcurgrx.c
93
 * (to prevent automatic graphical library inclusion)
94
 */
95
 
96
//#include <string.h>
97
//#include <stdlib.h>
98
//#include <cons.h>
99
//#include <mem.h>
100
 
101
//#include "vm.h"
102
#include <kernel/kern.h>
103
//#include "exc.h"
104
 
105
#include <drivers/mouse.h>
106
 
107
/*if defined: then a trace of the initialization is performed */
108
// #define __DEBUG_INIT__
109
 
110
/* if defined: when a byte is received is displayed on the screen */
111
//#define __XTRA_DEBUG_MOUSE__
112
 
113
/*
114
 *
115
 * Operation on a virtual mouse
116
 * (added by MG)
117
 *
118
 */
119
 
120
#include "_mouse.h"
121
#include "sermouse.h"
122
#include "ps2mouse.h"
123
 
124
struct mouse_operations vmouse[]={
125
 
126
  {"ms",   "The original ms protocol, with a middle-button extension.",
127
           {0x40, 0x40, 0x40, 0x00}, 3, 1, 0, 0, 0,
128
    sermouse_open,
129
    sermouse_close,
130
    sermouse_wait,
131
    sermouse_get,
132
    sermouse_enable,
133
    sermouse_disable,
134
    M_ms
135
  },
136
 
137
  {"ms+",  "Like 'ms', but allows dragging with the middle button.",
138
           {0x40, 0x40, 0x40, 0x00}, 3, 1, 0, 0, 0,
139
    sermouse_open,
140
    sermouse_close,
141
    sermouse_wait,
142
    sermouse_get,
143
    sermouse_enable,
144
    sermouse_disable,
145
    M_ms_plus
146
  },
147
 
148
  {"ms+lr", "'ms+', but you can reset m by pressing lr.",
149
            {0x40, 0x40, 0x40, 0x00}, 3, 1, 0, 0, 0,
150
    sermouse_open,
151
    sermouse_close,
152
    sermouse_wait,
153
    sermouse_get,
154
    sermouse_enable,
155
    sermouse_disable,
156
    M_ms_plus_lr
157
  },
158
 
159
  {"bare", "Unadorned ms protocol. Needed with some 2-buttons mice.",
160
           {0x40, 0x40, 0x40, 0x00}, 3, 1, 0, 0, 0,
161
    sermouse_open,
162
    sermouse_close,
163
    sermouse_wait,
164
    sermouse_get,
165
    sermouse_enable,
166
    sermouse_disable,
167
    M_bare
168
  },
169
 
170
  {"msc",  "Mouse-Systems-Compatible (5bytes). Most 3-button mice.",
171
           {0xf8, 0x80, 0x00, 0x00}, 5, 1, 0, 0, 0,
172
    sermouse_open,
173
    sermouse_close,
174
    sermouse_wait,
175
    sermouse_get,
176
    sermouse_enable,
177
    sermouse_disable,
178
    M_msc
179
  },
180
 
181
  {"sun",  "'msc' protocol, but only 3 bytes per packet.",
182
           {0xf8, 0x80, 0x00, 0x00}, 3, 1, 0, 0, 0,
183
    sermouse_open,
184
    sermouse_close,
185
    sermouse_wait,
186
    sermouse_get,
187
    sermouse_enable,
188
    sermouse_disable,
189
    M_sun
190
  },
191
 
192
  {"mm",   "MM series. Probably an old protocol...",
193
           {0xe0, 0x80, 0x80, 0x00}, 3, 1, 0, 0, 0,
194
    sermouse_open,
195
    sermouse_close,
196
    sermouse_wait,
197
    sermouse_get,
198
    sermouse_enable,
199
    sermouse_disable,
200
    M_mm
201
  },
202
 
203
  {"logi", "Used in some Logitech devices (only serial).",
204
           {0xe0, 0x80, 0x80, 0x00}, 3, 1, 0, 0, 0,
205
    sermouse_open,
206
    sermouse_close,
207
    sermouse_wait,
208
    sermouse_get,
209
    sermouse_enable,
210
    sermouse_disable,
211
    M_logi
212
  },
213
 
214
  {"ps2",  "Busmice of the ps/2 series. Most busmice, actually.",
215
           {0xc0, 0x00, 0x00, 0x00}, 3, 1, 0, 0, 0,
216
    ps2mouse_open,
217
    ps2mouse_close,
218
    ps2mouse_wait,
219
    ps2mouse_get,
220
    ps2mouse_enable,
221
    ps2mouse_disable,
222
    M_ps2
223
  },
224
 
225
  {"\0",     "",
226
           {0, 0, 0, 0}, 0, 0, 0, 0, 0,
227
   NULL,
228
   NULL,
229
   NULL,
230
   NULL,
231
   NULL,
232
   NULL,
233
   NULL
234
  }
235
 
236
};
237
 
238
int  (*open_mouse)(void*);    /* open comunication device */
239
void (*close_mouse)(void);    /* close comunication device */
240
void (*wait_mouse)(void);     /* wait to have a BYTE (blocking operation)*/
241
int  (*get_mouse)(BYTE *);      /* get last BYTE */
242
void (*enable_mouse)(void);   /* enable interface */
243
void (*disable_mouse)(void);  /* disable interface */
244
 
245
char *name_mouse;             /* mouse name */
246
char *desc_mouse;             /* mouse description */
247
BYTE *proto_mouse;            /* mouse protocol (see below) */
248
int  packetlen_mouse;         /* mouse packet lenght */
249
 
250
int (*decode_mouse)(MOUSE_EVT *evt,unsigned char *data);
251
 
252
/*
253
 * proto_mouse is used to syncronize the device driver:
254
 * if A is the first byte read and B the second, this is a valid
255
 * start of a mouse protocol packet if
256
 * (A&proto_mouse[0])==proto_mouse[1])&&(b&proto_mouse[2])==proto_mouse[3])
257
 */
258
 
259
/* type of mouse to use for virtual operation */
260
int mousetype=NOMOUSE;
261
 
262
/* fill the variabled used to call the virtuals operations */
263
static void mouse_settype(int type)
264
{
265
    mousetype=type;
266
 
267
    open_mouse   =vmouse[mousetype].open;
268
    close_mouse  =vmouse[mousetype].close;
269
    wait_mouse   =vmouse[mousetype].wait;
270
    get_mouse    =vmouse[mousetype].get;
271
    enable_mouse =vmouse[mousetype].enable;
272
    disable_mouse=vmouse[mousetype].disable;
273
 
274
    name_mouse     =vmouse[mousetype].name;
275
    desc_mouse     =vmouse[mousetype].desc;
276
    proto_mouse    =vmouse[mousetype].proto;
277
    packetlen_mouse=vmouse[mousetype].packetlen;
278
 
279
    decode_mouse=vmouse[mousetype].decode;
280
}
281
 
282
/*
283
 *
284
 * end (operation on a virtual mouse)
285
 *
286
 */
287
 
288
/* MG: this are no "static" (they are used by sermouse.c, ps2mouse.c) */
289
/*     "threshold" renamed "mouse_thresholdlim" */
290
short int mouse_lim_x1 = 0;
291
short int mouse_lim_y1 = 0;
292
short int mouse_lim_x2 = 79;
293
short int mouse_lim_y2 = 24;
294
short int mouse_x = 40;
295
short int mouse_x_mick = 0;
296
short int mouse_y = 12;
297
short int mouse_y_mick = 0;
298
short int mouse_buttons = 0;
299
short int mouse_thresholdlim = 5;
300
MOUSE_HANDLER mouse_handler = NULL;
301
 
302
MOUSE_HANDLER user_mouse_handler = NULL;
303
int autocursormode=DISABLE;
304
 
305
static PID mouse_pid = NIL;
306
 
307
/*
308
 * this is a general mouse server
309
 * useable by most mouse protocol implementation
310
 */
311
 
312
TASK generalmouse_server(void)
313
{
314
  static MOUSE_EVT event;
315
  BYTE data[8];
316
  int index;
317
  int mickey;
318
 
319
#ifdef __XTRA_DEBUG_MOUSE__
320
  char str[40];
321
#endif
322
 
323
  index=0;
324
  for(;;) {
325
#ifdef __XTRA_DEBUG_MOUSE__
326
    puts_xy(0,11,WHITE,"Waiting..");
327
#endif
328
 
329
    /* wait for mouse data */
330
    wait_mouse();
331
 
332
    /* get mouse data */
333
    //data[index]=get_mouse();
334
    index+=get_mouse(data+index);
335
 
336
#ifdef __XTRA_DEBUG_MOUSE__
337
    sprintf(str,"Mouse data[%01d]: %2x",index,data[index]);
338
    puts_xy(0,12+index,WHITE,str);
339
#endif
340
 
341
    switch (index) {
342
      case 1:
343
        if ((data[0]&proto_mouse[0])!=proto_mouse[1]) index=0;
344
        break;
345
      case 2:
346
        if ((data[1]&proto_mouse[2])==proto_mouse[3]) index=0;
347
        break;
348
      default:
349
        if (index<packetlen_mouse) break;
350
 
351
        if (decode_mouse(&event,data)==0) {
352
 
353
          /* Y */
354
          mickey=event.dy;
355
          mouse_y_mick += mickey;
356
          while (mouse_y_mick > mouse_thresholdlim) {
357
            mouse_y++;
358
            mouse_y_mick -= mouse_thresholdlim;
359
          }
360
          while (mouse_y_mick < -mouse_thresholdlim) {
361
            mouse_y--;
362
            mouse_y_mick += mouse_thresholdlim;
363
          }
364
          if (mouse_y > mouse_lim_y2) mouse_y = mouse_lim_y2;
365
          else if (mouse_y < mouse_lim_y1) mouse_y = mouse_lim_y1;
366
          event.y=mouse_y;
367
 
368
          /* X */
369
          mickey = event.dx;
370
          mouse_x_mick += mickey;
371
          while (mouse_x_mick > mouse_thresholdlim) {
372
            mouse_x++;
373
            mouse_x_mick -= mouse_thresholdlim;
374
          }
375
          while (mouse_x_mick < -mouse_thresholdlim) {
376
            mouse_x--;
377
            mouse_x_mick += mouse_thresholdlim;
378
          }
379
          if (mouse_x > mouse_lim_x2) mouse_x = mouse_lim_x2;
380
          else if (mouse_x < mouse_lim_x1) mouse_x = mouse_lim_x1;
381
          event.x=mouse_x;
382
 
383
          /* mouse handler */
384
          if (mouse_handler!=NULL) mouse_handler(&event);
385
        }
386
 
387
        index-=packetlen_mouse;
388
        if (index!=0) memcpy(data,data+packetlen_mouse,index);
389
        break;
390
 
391
    } /* switch */
392
  } /* for */
393
}
394
 
395
/* [for SERIAL MOUSE] */
396
/* Well, this implementation is a little dispendious as we use  */
397
/* two different tasks, one as serial receiver, the other as    */
398
/* mouse-protocol decoder; this has been chosen in order to     */
399
/* make any mouse-protocol easier. We only need to rewrite the  */
400
/* the appropriate mouse packet interpreter                     */
401
 
402
/*
403
 * MG: rewritten to handle serial and PS/2 mouse and other mouses
404
 */
405
 
406
/* changed user interface */
407
 
408
 
409
int mouse_init(MOUSE_PARMS *parms)
410
{
411
  int status=0;
412
  TASK_MODEL *m;
413
  SOFT_TASK_MODEL base_m;
414
  MOUSE_PARMS mparms=BASE_MOUSE;
415
 
416
#ifdef __DEBUG_INIT__
417
  cprintf("mouse_init: START\n");
418
#endif
419
 
420
  if (mouse_pid != NIL) return -1;
421
  if (parms==NULL) parms=&mparms;
422
 
423
  /* default values */
424
 
425
#ifdef __DEBUG_INIT__
426
  cprintf("mouse_init: default values\n");
427
#endif
428
 
429
  if (parms->tm == (TASK_MODEL *)MOUSE_DEFAULT) {
430
    soft_task_default_model(base_m);
431
    soft_task_def_wcet(base_m,2000);
432
    soft_task_def_met(base_m,500);
433
    soft_task_def_period(base_m,8000);
434
    soft_task_def_system(base_m);
435
    soft_task_def_nokill(base_m);
436
    soft_task_def_aperiodic(base_m);
437
    m = (TASK_MODEL *)&base_m;
438
  }
439
  else
440
    m = parms->tm;
441
 
442
  /* try autodetect mouse() */
443
  if (parms->type==MOUSE_DEFAULT) {
444
    SERMOUSE_INFO *sinfoptr;
445
 
446
#ifdef __DEBUG_INIT__
447
    cprintf("mouse_init: try autodetecting\n");
448
#endif
449
 
450
    if (ps2mouse_present()) parms->type=PS2MOUSE;
451
    else {
452
      sinfoptr=sermouse_present();
453
      if (sinfoptr==NULL) return -2;
454
      parms->type=sinfoptr->type;
455
      parms->port=sinfoptr->port;
456
    }
457
  }
458
 
459
  mouse_settype(parms->type);
460
  switch(mousetype) {
461
  case PS2MOUSE:
462
    /* max PS/2 mouse rate: 40 event per second with 3 bytes per event */
463
    /* 120 bytes/sec -> 8 msec between activation (I hope)*/
464
 
465
#ifdef __DEBUG_INIT__
466
    cprintf("mouse_init: creating ps2 server task\n");
467
#endif
468
 
469
    if (parms->tm==(TASK_MODEL *)MOUSE_DEFAULT)
470
      soft_task_def_period(base_m,8000);
471
    mouse_pid=task_create("PS2Mouse",
472
                          ps2mouse_getserveraddr(),
473
                          m, NULL);
474
    if (mouse_pid==-1) return -3;
475
 
476
    //task_activate(mouse_pid);
477
 
478
#ifdef __DEBUG_INIT__
479
    cprintf("mouse_init: opening mouse\n");
480
#endif
481
 
482
    status=open_mouse((void*)&mouse_pid);
483
    break;
484
 
485
  case MSMOUSE:
486
  case MSPMOUSE:
487
  case MSPLRMOUSE:
488
  case BAREMOUSE:
489
  case MSCMOUSE:
490
  case SUNMOUSE:
491
  case LOGIMOUSE:
492
  case MMMOUSE:
493
    break;
494
  }
495
 
496
  if (status!=0) {
497
    task_kill(mouse_pid);
498
    mouse_pid=NIL;
499
    return -4;
500
  }
501
 
502
#ifdef __DEBUG_INIT__
503
  cputs("mouse_init: mouse activated\n");
504
#endif
505
 
506
  return 0;
507
}
508
 
509
void mouse_end(void)
510
{
511
  if (mouse_pid==NIL) return;
512
  task_kill(mouse_pid);
513
  mouse_pid=NIL;
514
  close_mouse();
515
}
516
 
517
/* MG: all the following procedure are modified */
518
/*     to use virtual operation                 */
519
 
520
void mouse_disable(void)
521
{
522
  disable_mouse();
523
}
524
 
525
void mouse_enable(void)
526
{
527
  enable_mouse();
528
}
529
 
530
void mouse_get(int *x,int *y,BYTE *button)
531
{
532
    if (x != NULL) *x = mouse_x;
533
    if (y != NULL) *y = mouse_y;
534
    if (button != NULL) *button = mouse_buttons;
535
}
536
 
537
void mouse_position(int x,int y)
538
{
539
    disable_mouse();
540
    mouse_x = x;
541
    mouse_y = y;
542
    enable_mouse();
543
}
544
 
545
void mouse_limit(int x1,int y1,int x2,int y2)
546
{
547
    disable_mouse();
548
    mouse_lim_x1 = x1;
549
    mouse_lim_y1 = y1;
550
    mouse_lim_x2 = x2;
551
    mouse_lim_y2 = y2;
552
    mouse_x = (x1+x2)/2;
553
    mouse_y = (y1+y2)/2;
554
    enable_mouse();
555
}
556
 
557
void mouse_threshold(unsigned t)
558
{
559
    disable_mouse();
560
    if (t < 1) t = 1;
561
    else if (t > 100) t = 100;
562
    mouse_thresholdlim = t;
563
    enable_mouse();
564
}
565
 
566
void mouse_hook(MOUSE_HANDLER h)
567
{
568
  /* changed to use the autocursor functions */
569
  if ((autocursormode&STATUSMASK)==DISABLE) {
570
    mouse_handler = h;
571
  } else {
572
    user_mouse_handler = h;
573
  }
574
}