Go to most recent revision | Details | 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 | ------------ |
||
23 | CVS : $Id: mouse.c,v 1.1 2003-03-24 10:54:17 pj Exp $ |
||
24 | |||
25 | File: $File$ |
||
26 | Revision: $Revision: 1.1 $ |
||
27 | Last update: $Date: 2003-03-24 10:54:17 $ |
||
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 | } |