Scrap PC98 support.
[dragonfly.git] / sys / dev / misc / syscons / scmouse.c
CommitLineData
984263bc
MD
1/*-
2 * Copyright (c) 1999 Kazutaka YOKOTA <yokota@zodiac.mech.utsunomiya-u.ac.jp>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer as
10 * the first lines of this file unmodified.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 *
26 * $FreeBSD: src/sys/dev/syscons/scmouse.c,v 1.12.2.3 2001/07/28 12:51:47 yokota Exp $
7aa7bdf5 27 * $DragonFly: src/sys/dev/misc/syscons/scmouse.c,v 1.7 2005/02/13 03:02:25 swildner Exp $
984263bc
MD
28 */
29
30#include "opt_syscons.h"
31
984263bc
MD
32#include <sys/param.h>
33#include <sys/systm.h>
34#include <sys/conf.h>
35#include <sys/signalvar.h>
36#include <sys/proc.h>
37#include <sys/tty.h>
38#include <sys/malloc.h>
39
40#include <machine/console.h>
41#include <machine/mouse.h>
42
1f2de5d4 43#include "syscons.h"
984263bc
MD
44
45#ifdef SC_TWOBUTTON_MOUSE
46#define SC_MOUSE_PASTEBUTTON MOUSE_BUTTON3DOWN /* right button */
47#define SC_MOUSE_EXTENDBUTTON MOUSE_BUTTON2DOWN /* not really used */
48#else
49#define SC_MOUSE_PASTEBUTTON MOUSE_BUTTON2DOWN /* middle button */
50#define SC_MOUSE_EXTENDBUTTON MOUSE_BUTTON3DOWN /* right button */
51#endif /* SC_TWOBUTTON_MOUSE */
52
53#define SC_WAKEUP_DELTA 20
54
984263bc
MD
55#ifndef SC_NO_SYSMOUSE
56
57/* local variables */
58static int cut_buffer_size;
59static u_char *cut_buffer;
60
61/* local functions */
62static void set_mouse_pos(scr_stat *scp);
63#ifndef SC_NO_CUTPASTE
64static int skip_spc_right(scr_stat *scp, int p);
65static int skip_spc_left(scr_stat *scp, int p);
66static void mouse_cut(scr_stat *scp);
67static void mouse_cut_start(scr_stat *scp);
68static void mouse_cut_end(scr_stat *scp);
69static void mouse_cut_word(scr_stat *scp);
70static void mouse_cut_line(scr_stat *scp);
71static void mouse_cut_extend(scr_stat *scp);
72static void mouse_paste(scr_stat *scp);
73#endif /* SC_NO_CUTPASTE */
74
75#ifndef SC_NO_CUTPASTE
76/* allocate a cut buffer */
77void
78sc_alloc_cut_buffer(scr_stat *scp, int wait)
79{
80 u_char *p;
81
82 if ((cut_buffer == NULL)
83 || (cut_buffer_size < scp->xsize * scp->ysize + 1)) {
84 p = cut_buffer;
85 cut_buffer = NULL;
86 if (p != NULL)
87 free(p, M_DEVBUF);
88 cut_buffer_size = scp->xsize * scp->ysize + 1;
bf22d4c1 89 p = malloc(cut_buffer_size, M_DEVBUF, (wait) ? M_WAITOK : M_NOWAIT);
984263bc
MD
90 if (p != NULL)
91 p[0] = '\0';
92 cut_buffer = p;
93 }
94}
95#endif /* SC_NO_CUTPASTE */
96
97/* move mouse */
98void
99sc_mouse_move(scr_stat *scp, int x, int y)
100{
101 int s;
102
103 s = spltty();
104 scp->mouse_xpos = scp->mouse_oldxpos = x;
105 scp->mouse_ypos = scp->mouse_oldypos = y;
106 if (scp->font_size <= 0)
107 scp->mouse_pos = scp->mouse_oldpos = 0;
108 else
109 scp->mouse_pos = scp->mouse_oldpos =
110 (y/scp->font_size - scp->yoff)*scp->xsize + x/8 - scp->xoff;
111 scp->status |= MOUSE_MOVED;
112 splx(s);
113}
114
115/* adjust mouse position */
116static void
117set_mouse_pos(scr_stat *scp)
118{
119 if (scp->mouse_xpos < scp->xoff*8)
120 scp->mouse_xpos = scp->xoff*8;
121 if (scp->mouse_ypos < scp->yoff*scp->font_size)
122 scp->mouse_ypos = scp->yoff*scp->font_size;
123 if (ISGRAPHSC(scp)) {
124 if (scp->mouse_xpos > scp->xpixel-1)
125 scp->mouse_xpos = scp->xpixel-1;
126 if (scp->mouse_ypos > scp->ypixel-1)
127 scp->mouse_ypos = scp->ypixel-1;
128 return;
129 } else {
130 if (scp->mouse_xpos > (scp->xsize + scp->xoff)*8 - 1)
131 scp->mouse_xpos = (scp->xsize + scp->xoff)*8 - 1;
132 if (scp->mouse_ypos > (scp->ysize + scp->yoff)*scp->font_size - 1)
133 scp->mouse_ypos = (scp->ysize + scp->yoff)*scp->font_size - 1;
134 }
135
136 if (scp->mouse_xpos != scp->mouse_oldxpos || scp->mouse_ypos != scp->mouse_oldypos) {
137 scp->status |= MOUSE_MOVED;
138 scp->mouse_pos =
139 (scp->mouse_ypos/scp->font_size - scp->yoff)*scp->xsize
140 + scp->mouse_xpos/8 - scp->xoff;
141#ifndef SC_NO_CUTPASTE
142 if ((scp->status & MOUSE_VISIBLE) && (scp->status & MOUSE_CUTTING))
143 mouse_cut(scp);
144#endif
145 }
146}
147
148#ifndef SC_NO_CUTPASTE
149
150void
151sc_draw_mouse_image(scr_stat *scp)
152{
153 if (ISGRAPHSC(scp))
154 return;
155
156 ++scp->sc->videoio_in_progress;
157 (*scp->rndr->draw_mouse)(scp, scp->mouse_xpos, scp->mouse_ypos, TRUE);
158 scp->mouse_oldpos = scp->mouse_pos;
159 scp->mouse_oldxpos = scp->mouse_xpos;
160 scp->mouse_oldypos = scp->mouse_ypos;
161 scp->status |= MOUSE_VISIBLE;
162 --scp->sc->videoio_in_progress;
163}
164
165void
166sc_remove_mouse_image(scr_stat *scp)
167{
168 int size;
169 int i;
170
171 if (ISGRAPHSC(scp))
172 return;
173
174 ++scp->sc->videoio_in_progress;
175 (*scp->rndr->draw_mouse)(scp,
176 (scp->mouse_oldpos%scp->xsize + scp->xoff)*8,
177 (scp->mouse_oldpos/scp->xsize + scp->yoff)
178 * scp->font_size,
179 FALSE);
180 size = scp->xsize*scp->ysize;
181 i = scp->mouse_oldpos;
182 mark_for_update(scp, i);
183 mark_for_update(scp, i);
984263bc
MD
184 if (i + scp->xsize + 1 < size) {
185 mark_for_update(scp, i + scp->xsize + 1);
186 } else if (i + scp->xsize < size) {
187 mark_for_update(scp, i + scp->xsize);
188 } else if (i + 1 < size) {
189 mark_for_update(scp, i + 1);
190 }
984263bc
MD
191 scp->status &= ~MOUSE_VISIBLE;
192 --scp->sc->videoio_in_progress;
193}
194
195int
196sc_inside_cutmark(scr_stat *scp, int pos)
197{
198 int start;
199 int end;
200
201 if (scp->mouse_cut_end < 0)
202 return FALSE;
203 if (scp->mouse_cut_start <= scp->mouse_cut_end) {
204 start = scp->mouse_cut_start;
205 end = scp->mouse_cut_end;
206 } else {
207 start = scp->mouse_cut_end;
208 end = scp->mouse_cut_start - 1;
209 }
210 return ((start <= pos) && (pos <= end));
211}
212
213void
214sc_remove_cutmarking(scr_stat *scp)
215{
216 int s;
217
218 s = spltty();
219 if (scp->mouse_cut_end >= 0) {
220 mark_for_update(scp, scp->mouse_cut_start);
221 mark_for_update(scp, scp->mouse_cut_end);
222 }
223 scp->mouse_cut_start = scp->xsize*scp->ysize;
224 scp->mouse_cut_end = -1;
225 splx(s);
226 scp->status &= ~MOUSE_CUTTING;
227}
228
229void
230sc_remove_all_cutmarkings(sc_softc_t *sc)
231{
232 scr_stat *scp;
233 int i;
234
235 /* delete cut markings in all vtys */
236 for (i = 0; i < sc->vtys; ++i) {
237 scp = SC_STAT(sc->dev[i]);
238 if (scp == NULL)
239 continue;
240 sc_remove_cutmarking(scp);
241 }
242}
243
244void
245sc_remove_all_mouse(sc_softc_t *sc)
246{
247 scr_stat *scp;
248 int i;
249
250 for (i = 0; i < sc->vtys; ++i) {
251 scp = SC_STAT(sc->dev[i]);
252 if (scp == NULL)
253 continue;
254 if (scp->status & MOUSE_VISIBLE) {
255 scp->status &= ~MOUSE_VISIBLE;
256 mark_all(scp);
257 }
258 }
259}
260
261#define IS_SPACE_CHAR(c) (((c) & 0xff) == ' ')
262
263/* skip spaces to right */
264static int
265skip_spc_right(scr_stat *scp, int p)
266{
267 int c;
268 int i;
269
270 for (i = p % scp->xsize; i < scp->xsize; ++i) {
271 c = sc_vtb_getc(&scp->vtb, p);
272 if (!IS_SPACE_CHAR(c))
273 break;
274 ++p;
275 }
276 return i;
277}
278
279/* skip spaces to left */
280static int
281skip_spc_left(scr_stat *scp, int p)
282{
283 int c;
284 int i;
285
286 for (i = p-- % scp->xsize - 1; i >= 0; --i) {
287 c = sc_vtb_getc(&scp->vtb, p);
288 if (!IS_SPACE_CHAR(c))
289 break;
290 --p;
291 }
292 return i;
293}
294
295/* copy marked region to the cut buffer */
296static void
297mouse_cut(scr_stat *scp)
298{
299 int start;
300 int end;
301 int from;
302 int to;
303 int blank;
304 int c;
305 int p;
306 int s;
307 int i;
308
309 start = scp->mouse_cut_start;
310 end = scp->mouse_cut_end;
311 if (scp->mouse_pos >= start) {
312 from = start;
313 to = end = scp->mouse_pos;
314 } else {
315 from = end = scp->mouse_pos;
316 to = start - 1;
317 }
318 for (p = from, i = blank = 0; p <= to; ++p) {
319 cut_buffer[i] = sc_vtb_getc(&scp->vtb, p);
320 /* remember the position of the last non-space char */
321 if (!IS_SPACE_CHAR(cut_buffer[i++]))
322 blank = i; /* the first space after the last non-space */
323 /* trim trailing blank when crossing lines */
324 if ((p % scp->xsize) == (scp->xsize - 1)) {
325 cut_buffer[blank] = '\r';
326 i = blank + 1;
327 }
328 }
329 cut_buffer[i] = '\0';
330
331 /* scan towards the end of the last line */
332 --p;
333 for (i = p % scp->xsize; i < scp->xsize; ++i) {
334 c = sc_vtb_getc(&scp->vtb, p);
335 if (!IS_SPACE_CHAR(c))
336 break;
337 ++p;
338 }
339 /* if there is nothing but blank chars, trim them, but mark towards eol */
340 if (i >= scp->xsize) {
341 if (end >= start)
342 to = end = p - 1;
343 else
344 to = start = p;
345 cut_buffer[blank++] = '\r';
346 cut_buffer[blank] = '\0';
347 }
348
349 /* remove the current marking */
350 s = spltty();
351 if (scp->mouse_cut_start <= scp->mouse_cut_end) {
352 mark_for_update(scp, scp->mouse_cut_start);
353 mark_for_update(scp, scp->mouse_cut_end);
354 } else if (scp->mouse_cut_end >= 0) {
355 mark_for_update(scp, scp->mouse_cut_end);
356 mark_for_update(scp, scp->mouse_cut_start);
357 }
358
359 /* mark the new region */
360 scp->mouse_cut_start = start;
361 scp->mouse_cut_end = end;
362 mark_for_update(scp, from);
363 mark_for_update(scp, to);
364 splx(s);
365}
366
367/* a mouse button is pressed, start cut operation */
368static void
369mouse_cut_start(scr_stat *scp)
370{
371 int i;
372 int j;
373 int s;
374
375 if (scp->status & MOUSE_VISIBLE) {
376 i = scp->mouse_cut_start;
377 j = scp->mouse_cut_end;
378 sc_remove_all_cutmarkings(scp->sc);
379 if (scp->mouse_pos == i && i == j) {
380 cut_buffer[0] = '\0';
381 } else if (skip_spc_right(scp, scp->mouse_pos) >= scp->xsize) {
382 /* if the pointer is on trailing blank chars, mark towards eol */
383 i = skip_spc_left(scp, scp->mouse_pos) + 1;
384 s = spltty();
385 scp->mouse_cut_start =
386 (scp->mouse_pos / scp->xsize) * scp->xsize + i;
387 scp->mouse_cut_end =
388 (scp->mouse_pos / scp->xsize + 1) * scp->xsize - 1;
389 splx(s);
390 cut_buffer[0] = '\r';
391 cut_buffer[1] = '\0';
392 scp->status |= MOUSE_CUTTING;
393 } else {
394 s = spltty();
395 scp->mouse_cut_start = scp->mouse_pos;
396 scp->mouse_cut_end = scp->mouse_cut_start;
397 splx(s);
398 cut_buffer[0] = sc_vtb_getc(&scp->vtb, scp->mouse_cut_start);
399 cut_buffer[1] = '\0';
400 scp->status |= MOUSE_CUTTING;
401 }
402 mark_all(scp); /* this is probably overkill XXX */
403 }
404}
405
406/* end of cut operation */
407static void
408mouse_cut_end(scr_stat *scp)
409{
410 if (scp->status & MOUSE_VISIBLE)
411 scp->status &= ~MOUSE_CUTTING;
412}
413
414/* copy a word under the mouse pointer */
415static void
416mouse_cut_word(scr_stat *scp)
417{
418 int start;
419 int end;
420 int sol;
421 int eol;
422 int c;
423 int s;
424 int i;
425 int j;
426
427 /*
428 * Because we don't have locale information in the kernel,
429 * we only distinguish space char and non-space chars. Punctuation
430 * chars, symbols and other regular chars are all treated alike.
431 */
432 if (scp->status & MOUSE_VISIBLE) {
433 /* remove the current cut mark */
434 s = spltty();
435 if (scp->mouse_cut_start <= scp->mouse_cut_end) {
436 mark_for_update(scp, scp->mouse_cut_start);
437 mark_for_update(scp, scp->mouse_cut_end);
438 } else if (scp->mouse_cut_end >= 0) {
439 mark_for_update(scp, scp->mouse_cut_end);
440 mark_for_update(scp, scp->mouse_cut_start);
441 }
442 scp->mouse_cut_start = scp->xsize*scp->ysize;
443 scp->mouse_cut_end = -1;
444 splx(s);
445
446 sol = (scp->mouse_pos / scp->xsize) * scp->xsize;
447 eol = sol + scp->xsize;
448 c = sc_vtb_getc(&scp->vtb, scp->mouse_pos);
449 if (IS_SPACE_CHAR(c)) {
450 /* blank space */
451 for (j = scp->mouse_pos; j >= sol; --j) {
452 c = sc_vtb_getc(&scp->vtb, j);
453 if (!IS_SPACE_CHAR(c))
454 break;
455 }
456 start = ++j;
457 for (j = scp->mouse_pos; j < eol; ++j) {
458 c = sc_vtb_getc(&scp->vtb, j);
459 if (!IS_SPACE_CHAR(c))
460 break;
461 }
462 end = j - 1;
463 } else {
464 /* non-space word */
465 for (j = scp->mouse_pos; j >= sol; --j) {
466 c = sc_vtb_getc(&scp->vtb, j);
467 if (IS_SPACE_CHAR(c))
468 break;
469 }
470 start = ++j;
471 for (j = scp->mouse_pos; j < eol; ++j) {
472 c = sc_vtb_getc(&scp->vtb, j);
473 if (IS_SPACE_CHAR(c))
474 break;
475 }
476 end = j - 1;
477 }
478
479 /* copy the found word */
480 for (i = 0, j = start; j <= end; ++j)
481 cut_buffer[i++] = sc_vtb_getc(&scp->vtb, j);
482 cut_buffer[i] = '\0';
483 scp->status |= MOUSE_CUTTING;
484
485 /* mark the region */
486 s = spltty();
487 scp->mouse_cut_start = start;
488 scp->mouse_cut_end = end;
489 mark_for_update(scp, start);
490 mark_for_update(scp, end);
491 splx(s);
492 }
493}
494
495/* copy a line under the mouse pointer */
496static void
497mouse_cut_line(scr_stat *scp)
498{
499 int s;
500 int i;
501 int j;
502
503 if (scp->status & MOUSE_VISIBLE) {
504 /* remove the current cut mark */
505 s = spltty();
506 if (scp->mouse_cut_start <= scp->mouse_cut_end) {
507 mark_for_update(scp, scp->mouse_cut_start);
508 mark_for_update(scp, scp->mouse_cut_end);
509 } else if (scp->mouse_cut_end >= 0) {
510 mark_for_update(scp, scp->mouse_cut_end);
511 mark_for_update(scp, scp->mouse_cut_start);
512 }
513
514 /* mark the entire line */
515 scp->mouse_cut_start =
516 (scp->mouse_pos / scp->xsize) * scp->xsize;
517 scp->mouse_cut_end = scp->mouse_cut_start + scp->xsize - 1;
518 mark_for_update(scp, scp->mouse_cut_start);
519 mark_for_update(scp, scp->mouse_cut_end);
520 splx(s);
521
522 /* copy the line into the cut buffer */
523 for (i = 0, j = scp->mouse_cut_start; j <= scp->mouse_cut_end; ++j)
524 cut_buffer[i++] = sc_vtb_getc(&scp->vtb, j);
525 cut_buffer[i++] = '\r';
526 cut_buffer[i] = '\0';
527 scp->status |= MOUSE_CUTTING;
528 }
529}
530
531/* extend the marked region to the mouse pointer position */
532static void
533mouse_cut_extend(scr_stat *scp)
534{
535 int start;
536 int end;
537 int s;
538
539 if ((scp->status & MOUSE_VISIBLE) && !(scp->status & MOUSE_CUTTING)
540 && (scp->mouse_cut_end >= 0)) {
541 if (scp->mouse_cut_start <= scp->mouse_cut_end) {
542 start = scp->mouse_cut_start;
543 end = scp->mouse_cut_end;
544 } else {
545 start = scp->mouse_cut_end;
546 end = scp->mouse_cut_start - 1;
547 }
548 s = spltty();
549 if (scp->mouse_pos > end) {
550 scp->mouse_cut_start = start;
551 scp->mouse_cut_end = end;
552 } else if (scp->mouse_pos < start) {
553 scp->mouse_cut_start = end + 1;
554 scp->mouse_cut_end = start;
555 } else {
556 if (scp->mouse_pos - start > end + 1 - scp->mouse_pos) {
557 scp->mouse_cut_start = start;
558 scp->mouse_cut_end = end;
559 } else {
560 scp->mouse_cut_start = end + 1;
561 scp->mouse_cut_end = start;
562 }
563 }
564 splx(s);
565 mouse_cut(scp);
566 scp->status |= MOUSE_CUTTING;
567 }
568}
569
570/* paste cut buffer contents into the current vty */
571static void
572mouse_paste(scr_stat *scp)
573{
574 if (scp->status & MOUSE_VISIBLE)
575 sc_paste(scp, cut_buffer, strlen(cut_buffer));
576}
577
578#endif /* SC_NO_CUTPASTE */
579
580int
581sc_mouse_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag,
41c20dac 582 struct thread *td)
984263bc
MD
583{
584 mouse_info_t *mouse;
984263bc
MD
585 scr_stat *cur_scp;
586 scr_stat *scp;
587 int s;
588 int f;
589
590 scp = SC_STAT(tp->t_dev);
591
592 switch (cmd) {
593
594 case CONS_MOUSECTL: /* control mouse arrow */
984263bc 595 mouse = (mouse_info_t*)data;
984263bc
MD
596 cur_scp = scp->sc->cur_scp;
597
598 switch (mouse->operation) {
599 case MOUSE_MODE:
600 if (ISSIGVALID(mouse->u.mode.signal)) {
601 scp->mouse_signal = mouse->u.mode.signal;
41c20dac
MD
602 scp->mouse_proc = td->td_proc;
603 scp->mouse_pid = td->td_proc->p_pid;
984263bc
MD
604 }
605 else {
606 scp->mouse_signal = 0;
607 scp->mouse_proc = NULL;
608 scp->mouse_pid = 0;
609 }
610 return 0;
611
612 case MOUSE_SHOW:
613 s = spltty();
614 if (!(scp->sc->flags & SC_MOUSE_ENABLED)) {
615 scp->sc->flags |= SC_MOUSE_ENABLED;
616 cur_scp->status &= ~MOUSE_HIDDEN;
617 if (!ISGRAPHSC(cur_scp))
618 mark_all(cur_scp);
619 splx(s);
620 return 0;
621 } else {
622 splx(s);
623 return EINVAL;
624 }
625 break;
626
627 case MOUSE_HIDE:
628 s = spltty();
629 if (scp->sc->flags & SC_MOUSE_ENABLED) {
630 scp->sc->flags &= ~SC_MOUSE_ENABLED;
631 sc_remove_all_mouse(scp->sc);
632 splx(s);
633 return 0;
634 } else {
635 splx(s);
636 return EINVAL;
637 }
638 break;
639
640 case MOUSE_MOVEABS:
641 s = spltty();
642 scp->mouse_xpos = mouse->u.data.x;
643 scp->mouse_ypos = mouse->u.data.y;
644 set_mouse_pos(scp);
645 splx(s);
646 break;
647
648 case MOUSE_MOVEREL:
649 s = spltty();
650 scp->mouse_xpos += mouse->u.data.x;
651 scp->mouse_ypos += mouse->u.data.y;
652 set_mouse_pos(scp);
653 splx(s);
654 break;
655
656 case MOUSE_GETINFO:
657 mouse->u.data.x = scp->mouse_xpos;
658 mouse->u.data.y = scp->mouse_ypos;
659 mouse->u.data.z = 0;
660 mouse->u.data.buttons = scp->mouse_buttons;
661 return 0;
662
663 case MOUSE_ACTION:
664 case MOUSE_MOTION_EVENT:
665 /* send out mouse event on /dev/sysmouse */
666#if 0
667 /* this should maybe only be settable from /dev/consolectl SOS */
668 if (SC_VTY(tp->t_dev) != SC_CONSOLECTL)
669 return ENOTTY;
670#endif
671 s = spltty();
672 if (mouse->u.data.x != 0 || mouse->u.data.y != 0) {
673 cur_scp->mouse_xpos += mouse->u.data.x;
674 cur_scp->mouse_ypos += mouse->u.data.y;
675 set_mouse_pos(cur_scp);
676 }
677 f = 0;
678 if (mouse->operation == MOUSE_ACTION) {
679 f = cur_scp->mouse_buttons ^ mouse->u.data.buttons;
680 cur_scp->mouse_buttons = mouse->u.data.buttons;
681 }
682 splx(s);
683
684 if (sysmouse_event(mouse) == 0)
685 return 0;
686
687 /*
688 * If any buttons are down or the mouse has moved a lot,
689 * stop the screen saver.
690 */
691 if (((mouse->operation == MOUSE_ACTION) && mouse->u.data.buttons)
692 || (mouse->u.data.x*mouse->u.data.x
693 + mouse->u.data.y*mouse->u.data.y
694 >= SC_WAKEUP_DELTA*SC_WAKEUP_DELTA)) {
695 sc_touch_scrn_saver();
696 }
697
698 cur_scp->status &= ~MOUSE_HIDDEN;
699
700 if (cur_scp->mouse_signal) {
701 /* has controlling process died? */
702 if (cur_scp->mouse_proc &&
703 (cur_scp->mouse_proc != pfind(cur_scp->mouse_pid))){
704 cur_scp->mouse_signal = 0;
705 cur_scp->mouse_proc = NULL;
706 cur_scp->mouse_pid = 0;
707 } else {
708 psignal(cur_scp->mouse_proc, cur_scp->mouse_signal);
709 break;
710 }
711 }
712
713 if (ISGRAPHSC(cur_scp) || (cut_buffer == NULL))
714 break;
715
716#ifndef SC_NO_CUTPASTE
717 if ((mouse->operation == MOUSE_ACTION) && f) {
718 /* process button presses */
719 if (cur_scp->mouse_buttons & MOUSE_BUTTON1DOWN)
720 mouse_cut_start(cur_scp);
721 else
722 mouse_cut_end(cur_scp);
723 if (cur_scp->mouse_buttons & MOUSE_BUTTON2DOWN ||
724 cur_scp->mouse_buttons & MOUSE_BUTTON3DOWN)
725 mouse_paste(cur_scp);
726 }
727#endif /* SC_NO_CUTPASTE */
728 break;
729
730 case MOUSE_BUTTON_EVENT:
731 if ((mouse->u.event.id & MOUSE_BUTTONS) == 0)
732 return EINVAL;
733 if (mouse->u.event.value < 0)
734 return EINVAL;
735#if 0
736 /* this should maybe only be settable from /dev/consolectl SOS */
737 if (SC_VTY(tp->t_dev) != SC_CONSOLECTL)
738 return ENOTTY;
739#endif
740 if (mouse->u.event.value > 0)
741 cur_scp->mouse_buttons |= mouse->u.event.id;
742 else
743 cur_scp->mouse_buttons &= ~mouse->u.event.id;
744
745 if (sysmouse_event(mouse) == 0)
746 return 0;
747
748 /* if a button is held down, stop the screen saver */
749 if (mouse->u.event.value > 0)
750 sc_touch_scrn_saver();
751
752 cur_scp->status &= ~MOUSE_HIDDEN;
753
754 if (cur_scp->mouse_signal) {
755 if (cur_scp->mouse_proc &&
756 (cur_scp->mouse_proc != pfind(cur_scp->mouse_pid))){
757 cur_scp->mouse_signal = 0;
758 cur_scp->mouse_proc = NULL;
759 cur_scp->mouse_pid = 0;
760 } else {
761 psignal(cur_scp->mouse_proc, cur_scp->mouse_signal);
762 break;
763 }
764 }
765
766 if (ISGRAPHSC(cur_scp) || (cut_buffer == NULL))
767 break;
768
769#ifndef SC_NO_CUTPASTE
770 switch (mouse->u.event.id) {
771 case MOUSE_BUTTON1DOWN:
772 switch (mouse->u.event.value % 4) {
773 case 0: /* up */
774 mouse_cut_end(cur_scp);
775 break;
776 case 1: /* single click: start cut operation */
777 mouse_cut_start(cur_scp);
778 break;
779 case 2: /* double click: cut a word */
780 mouse_cut_word(cur_scp);
781 mouse_cut_end(cur_scp);
782 break;
783 case 3: /* triple click: cut a line */
784 mouse_cut_line(cur_scp);
785 mouse_cut_end(cur_scp);
786 break;
787 }
788 break;
789 case SC_MOUSE_PASTEBUTTON:
790 switch (mouse->u.event.value) {
791 case 0: /* up */
792 break;
793 default:
794 mouse_paste(cur_scp);
795 break;
796 }
797 break;
798 case SC_MOUSE_EXTENDBUTTON:
799 switch (mouse->u.event.value) {
800 case 0: /* up */
801 if (!(cur_scp->mouse_buttons & MOUSE_BUTTON1DOWN))
802 mouse_cut_end(cur_scp);
803 break;
804 default:
805 mouse_cut_extend(cur_scp);
806 break;
807 }
808 break;
809 }
810#endif /* SC_NO_CUTPASTE */
811 break;
812
813 case MOUSE_MOUSECHAR:
814 if (mouse->u.mouse_char < 0) {
815 mouse->u.mouse_char = scp->sc->mouse_char;
816 } else {
1f2de5d4 817 if (mouse->u.mouse_char >= (unsigned char)-1 - 4)
984263bc
MD
818 return EINVAL;
819 s = spltty();
820 sc_remove_all_mouse(scp->sc);
821#ifndef SC_NO_FONT_LOADING
822 if (ISTEXTSC(cur_scp) && (cur_scp->font != NULL))
823 sc_load_font(cur_scp, 0, cur_scp->font_size, cur_scp->font,
824 cur_scp->sc->mouse_char, 4);
825#endif
826 scp->sc->mouse_char = mouse->u.mouse_char;
827 splx(s);
828 }
829 break;
830
831 default:
832 return EINVAL;
833 }
834
835 return 0;
836 }
837
838 return ENOIOCTL;
839}
840
841#endif /* SC_NO_SYSMOUSE */