Subversion Repositories shark

Rev

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

Rev Author Line No. Line
2 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
 ------------
23
 CVS :        $Id: mouse.c,v 1.1.1.1 2002-03-29 14:12:49 pj Exp $
24
 
25
 File:        $File$
26
 Revision:    $Revision: 1.1.1.1 $
27
 Last update: $Date: 2002-03-29 14:12:49 $
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/scom.h>
106
#include <drivers/mouse.h>
107
 
108
/*if defined: then a trace of the initialization is performed */
109
// #define __DEBUG_INIT__
110
 
111
/* if defined: when a byte is received is displayed on the screen */
112
//#define __XTRA_DEBUG_MOUSE__
113
 
114
/*
115
 *
116
 * Operation on a virtual mouse
117
 * (added by MG)
118
 *
119
 */
120
 
121
#include "_mouse.h"
122
#include "sermouse.h"
123
#include "ps2mouse.h"
124
 
125
struct mouse_operations vmouse[]={
126
 
127
  {"ms",   "The original ms protocol, with a middle-button extension.",
128
           {0x40, 0x40, 0x40, 0x00}, 3, 1, 0, 0, 0,
129
    sermouse_open,
130
    sermouse_close,
131
    sermouse_wait,
132
    sermouse_get,
133
    sermouse_enable,
134
    sermouse_disable,
135
    M_ms
136
  },
137
 
138
  {"ms+",  "Like 'ms', but allows dragging with the middle button.",
139
           {0x40, 0x40, 0x40, 0x00}, 3, 1, 0, 0, 0,
140
    sermouse_open,
141
    sermouse_close,
142
    sermouse_wait,
143
    sermouse_get,
144
    sermouse_enable,
145
    sermouse_disable,
146
    M_ms_plus
147
  },
148
 
149
  {"ms+lr", "'ms+', but you can reset m by pressing lr.",
150
            {0x40, 0x40, 0x40, 0x00}, 3, 1, 0, 0, 0,
151
    sermouse_open,
152
    sermouse_close,
153
    sermouse_wait,
154
    sermouse_get,
155
    sermouse_enable,
156
    sermouse_disable,
157
    M_ms_plus_lr
158
  },
159
 
160
  {"bare", "Unadorned ms protocol. Needed with some 2-buttons mice.",
161
           {0x40, 0x40, 0x40, 0x00}, 3, 1, 0, 0, 0,
162
    sermouse_open,
163
    sermouse_close,
164
    sermouse_wait,
165
    sermouse_get,
166
    sermouse_enable,
167
    sermouse_disable,
168
    M_bare
169
  },
170
 
171
  {"msc",  "Mouse-Systems-Compatible (5bytes). Most 3-button mice.",
172
           {0xf8, 0x80, 0x00, 0x00}, 5, 1, 0, 0, 0,
173
    sermouse_open,
174
    sermouse_close,
175
    sermouse_wait,
176
    sermouse_get,
177
    sermouse_enable,
178
    sermouse_disable,
179
    M_msc
180
  },
181
 
182
  {"sun",  "'msc' protocol, but only 3 bytes per packet.",
183
           {0xf8, 0x80, 0x00, 0x00}, 3, 1, 0, 0, 0,
184
    sermouse_open,
185
    sermouse_close,
186
    sermouse_wait,
187
    sermouse_get,
188
    sermouse_enable,
189
    sermouse_disable,
190
    M_sun
191
  },
192
 
193
  {"mm",   "MM series. Probably an old protocol...",
194
           {0xe0, 0x80, 0x80, 0x00}, 3, 1, 0, 0, 0,
195
    sermouse_open,
196
    sermouse_close,
197
    sermouse_wait,
198
    sermouse_get,
199
    sermouse_enable,
200
    sermouse_disable,
201
    M_mm
202
  },
203
 
204
  {"logi", "Used in some Logitech devices (only serial).",
205
           {0xe0, 0x80, 0x80, 0x00}, 3, 1, 0, 0, 0,
206
    sermouse_open,
207
    sermouse_close,
208
    sermouse_wait,
209
    sermouse_get,
210
    sermouse_enable,
211
    sermouse_disable,
212
    M_logi
213
  },
214
 
215
  {"ps2",  "Busmice of the ps/2 series. Most busmice, actually.",
216
           {0xc0, 0x00, 0x00, 0x00}, 3, 1, 0, 0, 0,
217
    ps2mouse_open,
218
    ps2mouse_close,
219
    ps2mouse_wait,
220
    ps2mouse_get,
221
    ps2mouse_enable,
222
    ps2mouse_disable,
223
    M_ps2
224
  },
225
 
226
  {"\0",     "",
227
           {0, 0, 0, 0}, 0, 0, 0, 0, 0,
228
   NULL,
229
   NULL,
230
   NULL,
231
   NULL,
232
   NULL,
233
   NULL,
234
   NULL
235
  }
236
 
237
};
238
 
239
int  (*open_mouse)(void*);    /* open comunication device */
240
void (*close_mouse)(void);    /* close comunication device */
241
void (*wait_mouse)(void);     /* wait to have a BYTE (blocking operation)*/
242
int  (*get_mouse)(BYTE *);      /* get last BYTE */
243
void (*enable_mouse)(void);   /* enable interface */
244
void (*disable_mouse)(void);  /* disable interface */
245
 
246
char *name_mouse;             /* mouse name */
247
char *desc_mouse;             /* mouse description */
248
BYTE *proto_mouse;            /* mouse protocol (see below) */
249
int  packetlen_mouse;         /* mouse packet lenght */
250
 
251
int (*decode_mouse)(MOUSE_EVT *evt,unsigned char *data);
252
 
253
/*
254
 * proto_mouse is used to syncronize the device driver:
255
 * if A is the first byte read and B the second, this is a valid
256
 * start of a mouse protocol packet if
257
 * (A&proto_mouse[0])==proto_mouse[1])&&(b&proto_mouse[2])==proto_mouse[3])
258
 */
259
 
260
/* type of mouse to use for virtual operation */
261
int mousetype=NOMOUSE;
262
 
263
/* fill the variabled used to call the virtuals operations */
264
static void mouse_settype(int type)
265
{
266
    mousetype=type;
267
 
268
    open_mouse   =vmouse[mousetype].open;
269
    close_mouse  =vmouse[mousetype].close;
270
    wait_mouse   =vmouse[mousetype].wait;
271
    get_mouse    =vmouse[mousetype].get;
272
    enable_mouse =vmouse[mousetype].enable;
273
    disable_mouse=vmouse[mousetype].disable;
274
 
275
    name_mouse     =vmouse[mousetype].name;
276
    desc_mouse     =vmouse[mousetype].desc;
277
    proto_mouse    =vmouse[mousetype].proto;
278
    packetlen_mouse=vmouse[mousetype].packetlen;
279
 
280
    decode_mouse=vmouse[mousetype].decode;
281
}
282
 
283
/*
284
 *
285
 * end (operation on a virtual mouse)
286
 *
287
 */
288
 
289
/* MG: this are no "static" (they are used by sermouse.c, ps2mouse.c) */
290
/*     "threshold" renamed "mouse_thresholdlim" */
291
short int mouse_lim_x1 = 0;
292
short int mouse_lim_y1 = 0;
293
short int mouse_lim_x2 = 79;
294
short int mouse_lim_y2 = 24;
295
short int mouse_x = 40;
296
short int mouse_x_mick = 0;
297
short int mouse_y = 12;
298
short int mouse_y_mick = 0;
299
short int mouse_buttons = 0;
300
short int mouse_thresholdlim = 5;
301
MOUSE_HANDLER mouse_handler = NULL;
302
 
303
MOUSE_HANDLER user_mouse_handler = NULL;
304
int autocursormode=DISABLE;
305
 
306
static PID mouse_pid = NIL;
307
 
308
/*
309
 * this is a general mouse server
310
 * useable by most mouse protocol implementation
311
 */
312
 
313
TASK generalmouse_server(void)
314
{
315
  static MOUSE_EVT event;
316
  BYTE data[8];
317
  int index;
318
  int mickey;
319
 
320
#ifdef __XTRA_DEBUG_MOUSE__
321
  char str[40];
322
#endif
323
 
324
  index=0;
325
  for(;;) {
326
#ifdef __XTRA_DEBUG_MOUSE__
327
    puts_xy(0,11,WHITE,"Waiting..");
328
#endif
329
 
330
    /* wait for mouse data */
331
    wait_mouse();
332
 
333
    /* get mouse data */
334
    //data[index]=get_mouse();
335
    index+=get_mouse(data+index);
336
 
337
#ifdef __XTRA_DEBUG_MOUSE__
338
    sprintf(str,"Mouse data[%01d]: %2x",index,data[index]);
339
    puts_xy(0,12+index,WHITE,str);
340
#endif
341
 
342
    switch (index) {
343
      case 1:
344
        if ((data[0]&proto_mouse[0])!=proto_mouse[1]) index=0;
345
        break;
346
      case 2:
347
        if ((data[1]&proto_mouse[2])==proto_mouse[3]) index=0;
348
        break;
349
      default:
350
        if (index<packetlen_mouse) break;
351
 
352
        if (decode_mouse(&event,data)==0) {
353
 
354
          /* Y */
355
          mickey=event.dy;
356
          mouse_y_mick += mickey;
357
          while (mouse_y_mick > mouse_thresholdlim) {
358
            mouse_y++;
359
            mouse_y_mick -= mouse_thresholdlim;
360
          }
361
          while (mouse_y_mick < -mouse_thresholdlim) {
362
            mouse_y--;
363
            mouse_y_mick += mouse_thresholdlim;
364
          }
365
          if (mouse_y > mouse_lim_y2) mouse_y = mouse_lim_y2;
366
          else if (mouse_y < mouse_lim_y1) mouse_y = mouse_lim_y1;
367
          event.y=mouse_y;
368
 
369
          /* X */
370
          mickey = event.dx;
371
          mouse_x_mick += mickey;
372
          while (mouse_x_mick > mouse_thresholdlim) {
373
            mouse_x++;
374
            mouse_x_mick -= mouse_thresholdlim;
375
          }
376
          while (mouse_x_mick < -mouse_thresholdlim) {
377
            mouse_x--;
378
            mouse_x_mick += mouse_thresholdlim;
379
          }
380
          if (mouse_x > mouse_lim_x2) mouse_x = mouse_lim_x2;
381
          else if (mouse_x < mouse_lim_x1) mouse_x = mouse_lim_x1;
382
          event.x=mouse_x;
383
 
384
          /* mouse handler */
385
          if (mouse_handler!=NULL) mouse_handler(&event);
386
        }
387
 
388
        index-=packetlen_mouse;
389
        if (index!=0) memcpy(data,data+packetlen_mouse,index);
390
        break;
391
 
392
    } /* switch */
393
  } /* for */
394
}
395
 
396
/* [for SERIAL MOUSE] */
397
/* Well, this implementation is a little dispendious as we use  */
398
/* two different tasks, one as serial receiver, the other as    */
399
/* mouse-protocol decoder; this has been chosen in order to     */
400
/* make any mouse-protocol easier. We only need to rewrite the  */
401
/* the appropriate mouse packet interpreter                     */
402
 
403
/*
404
 * MG: rewritten to handle serial and PS/2 mouse and other mouses
405
 */
406
 
407
/* changed user interface */
408
 
409
 
410
int mouse_init(MOUSE_PARMS *parms)
411
{
412
  int status=0;
413
  TASK_MODEL *m;
414
  SOFT_TASK_MODEL base_m;
415
  SERMOUSE_INFO sinfo;
416
  MOUSE_PARMS mparms=BASE_MOUSE;
417
 
418
#ifdef __DEBUG_INIT__
419
  cprintf("mouse_init: START\n");
420
#endif
421
 
422
  if (mouse_pid != NIL) return -1;
423
  if (parms==NULL) parms=&mparms;
424
 
425
  /* default values */
426
 
427
#ifdef __DEBUG_INIT__
428
  cprintf("mouse_init: default values\n");
429
#endif
430
 
431
  if (parms->tm == (TASK_MODEL *)MOUSE_DEFAULT) {
432
    soft_task_default_model(base_m);
433
    soft_task_def_wcet(base_m,2000);
434
    soft_task_def_met(base_m,500);
435
    soft_task_def_period(base_m,8000);
436
    soft_task_def_system(base_m);
437
    soft_task_def_nokill(base_m);
438
    soft_task_def_aperiodic(base_m);
439
    m = (TASK_MODEL *)&base_m;
440
  }
441
  else
442
    m = parms->tm;
443
 
444
  /* try autodetect mouse() */
445
  if (parms->type==MOUSE_DEFAULT) {
446
    SERMOUSE_INFO *sinfoptr;
447
 
448
#ifdef __DEBUG_INIT__
449
    cprintf("mouse_init: try autodetecting\n");
450
#endif
451
 
452
    if (ps2mouse_present()) parms->type=PS2MOUSE;
453
    else {
454
      sinfoptr=sermouse_present();
455
      if (sinfoptr==NULL) return -2;
456
      parms->type=sinfoptr->type;
457
      parms->port=sinfoptr->port;
458
    }
459
  }
460
 
461
  mouse_settype(parms->type);
462
  switch(mousetype) {
463
  case PS2MOUSE:
464
    /* max PS/2 mouse rate: 40 event per second with 3 bytes per event */
465
    /* 120 bytes/sec -> 8 msec between activation (I hope)*/
466
 
467
#ifdef __DEBUG_INIT__
468
    cprintf("mouse_init: creating ps2 server task\n");
469
#endif
470
 
471
    if (parms->tm==(TASK_MODEL *)MOUSE_DEFAULT)
472
      soft_task_def_period(base_m,8000);
473
    mouse_pid=task_create("PS2Mouse",
474
                          ps2mouse_getserveraddr(),
475
                          m, NULL);
476
    if (mouse_pid==-1) return -3;
477
 
478
    //task_activate(mouse_pid);
479
 
480
#ifdef __DEBUG_INIT__
481
    cprintf("mouse_init: opening mouse\n");
482
#endif
483
 
484
    status=open_mouse((void*)&mouse_pid);
485
    break;
486
 
487
  case MSMOUSE:
488
  case MSPMOUSE:
489
  case MSPLRMOUSE:
490
  case BAREMOUSE:
491
  case MSCMOUSE:
492
  case SUNMOUSE:
493
  case LOGIMOUSE:
494
  case MMMOUSE:
495
    if (parms->port==MOUSE_DEFAULT) parms->port=COM1;
496
    sinfo.type=parms->type;
497
    sinfo.port=parms->port;
498
    if (parms->tm == (TASK_MODEL *)MOUSE_DEFAULT)
499
      soft_task_def_period(base_m,12000);
500
    task_def_arg(*m,(void *)parms->port);
501
    mouse_pid=task_create("SerialMouse",
502
                          sermouse_getserveraddr(&sinfo),
503
                          m, NULL);
504
 
505
    if (mouse_pid==-1) return -3;
506
    sinfo.pid=mouse_pid;
507
    status=open_mouse((void*)&sinfo);
508
    //if (!status)
509
    //  task_activate(mouse_pid);
510
    break;
511
  }
512
 
513
  if (status!=0) {
514
    task_kill(mouse_pid);
515
    mouse_pid=NIL;
516
    return -4;
517
  }
518
 
519
#ifdef __DEBUG_INIT__
520
  cputs("mouse_init: mouse activated\n");
521
#endif
522
 
523
  return 0;
524
}
525
 
526
void mouse_end(void)
527
{
528
  if (mouse_pid==NIL) return;
529
  task_kill(mouse_pid);
530
  mouse_pid=NIL;
531
  close_mouse();
532
}
533
 
534
/* MG: all the following procedure are modified */
535
/*     to use virtual operation                 */
536
 
537
void mouse_disable(void)
538
{
539
  disable_mouse();
540
}
541
 
542
void mouse_enable(void)
543
{
544
  enable_mouse();
545
}
546
 
547
void mouse_get(int *x,int *y,BYTE *button)
548
{
549
    if (x != NULL) *x = mouse_x;
550
    if (y != NULL) *y = mouse_y;
551
    if (button != NULL) *button = mouse_buttons;
552
}
553
 
554
void mouse_position(int x,int y)
555
{
556
    disable_mouse();
557
    mouse_x = x;
558
    mouse_y = y;
559
    enable_mouse();
560
}
561
 
562
void mouse_limit(int x1,int y1,int x2,int y2)
563
{
564
    disable_mouse();
565
    mouse_lim_x1 = x1;
566
    mouse_lim_y1 = y1;
567
    mouse_lim_x2 = x2;
568
    mouse_lim_y2 = y2;
569
    mouse_x = (x1+x2)/2;
570
    mouse_y = (y1+y2)/2;
571
    enable_mouse();
572
}
573
 
574
void mouse_threshold(unsigned t)
575
{
576
    disable_mouse();
577
    if (t < 1) t = 1;
578
    else if (t > 100) t = 100;
579
    mouse_thresholdlim = t;
580
    enable_mouse();
581
}
582
 
583
void mouse_hook(MOUSE_HANDLER h)
584
{
585
  /* changed to use the autocursor functions */
586
  if ((autocursormode&STATUSMASK)==DISABLE) {
587
    mouse_handler = h;
588
  } else {
589
    user_mouse_handler = h;
590
  }
591
}